diff --git a/crc16_test/crc16.cpp b/crc16_test/crc16.cpp new file mode 100644 index 0000000..ee35710 --- /dev/null +++ b/crc16_test/crc16.cpp @@ -0,0 +1,51 @@ +#include "Arduino.h" +#include "crc16.h" + +const unsigned int TABLE[] = { + 0X0000, 0XC0C1, 0XC181, 0X0140, 0XC301, 0X03C0, 0X0280, 0XC241, + 0XC601, 0X06C0, 0X0780, 0XC741, 0X0500, 0XC5C1, 0XC481, 0X0440, + 0XCC01, 0X0CC0, 0X0D80, 0XCD41, 0X0F00, 0XCFC1, 0XCE81, 0X0E40, + 0X0A00, 0XCAC1, 0XCB81, 0X0B40, 0XC901, 0X09C0, 0X0880, 0XC841, + 0XD801, 0X18C0, 0X1980, 0XD941, 0X1B00, 0XDBC1, 0XDA81, 0X1A40, + 0X1E00, 0XDEC1, 0XDF81, 0X1F40, 0XDD01, 0X1DC0, 0X1C80, 0XDC41, + 0X1400, 0XD4C1, 0XD581, 0X1540, 0XD701, 0X17C0, 0X1680, 0XD641, + 0XD201, 0X12C0, 0X1380, 0XD341, 0X1100, 0XD1C1, 0XD081, 0X1040, + 0XF001, 0X30C0, 0X3180, 0XF141, 0X3300, 0XF3C1, 0XF281, 0X3240, + 0X3600, 0XF6C1, 0XF781, 0X3740, 0XF501, 0X35C0, 0X3480, 0XF441, + 0X3C00, 0XFCC1, 0XFD81, 0X3D40, 0XFF01, 0X3FC0, 0X3E80, 0XFE41, + 0XFA01, 0X3AC0, 0X3B80, 0XFB41, 0X3900, 0XF9C1, 0XF881, 0X3840, + 0X2800, 0XE8C1, 0XE981, 0X2940, 0XEB01, 0X2BC0, 0X2A80, 0XEA41, + 0XEE01, 0X2EC0, 0X2F80, 0XEF41, 0X2D00, 0XEDC1, 0XEC81, 0X2C40, + 0XE401, 0X24C0, 0X2580, 0XE541, 0X2700, 0XE7C1, 0XE681, 0X2640, + 0X2200, 0XE2C1, 0XE381, 0X2340, 0XE101, 0X21C0, 0X2080, 0XE041, + 0XA001, 0X60C0, 0X6180, 0XA141, 0X6300, 0XA3C1, 0XA281, 0X6240, + 0X6600, 0XA6C1, 0XA781, 0X6740, 0XA501, 0X65C0, 0X6480, 0XA441, + 0X6C00, 0XACC1, 0XAD81, 0X6D40, 0XAF01, 0X6FC0, 0X6E80, 0XAE41, + 0XAA01, 0X6AC0, 0X6B80, 0XAB41, 0X6900, 0XA9C1, 0XA881, 0X6840, + 0X7800, 0XB8C1, 0XB981, 0X7940, 0XBB01, 0X7BC0, 0X7A80, 0XBA41, + 0XBE01, 0X7EC0, 0X7F80, 0XBF41, 0X7D00, 0XBDC1, 0XBC81, 0X7C40, + 0XB401, 0X74C0, 0X7580, 0XB541, 0X7700, 0XB7C1, 0XB681, 0X7640, + 0X7200, 0XB2C1, 0XB381, 0X7340, 0XB101, 0X71C0, 0X7080, 0XB041, + 0X5000, 0X90C1, 0X9181, 0X5140, 0X9301, 0X53C0, 0X5280, 0X9241, + 0X9601, 0X56C0, 0X5780, 0X9741, 0X5500, 0X95C1, 0X9481, 0X5440, + 0X9C01, 0X5CC0, 0X5D80, 0X9D41, 0X5F00, 0X9FC1, 0X9E81, 0X5E40, + 0X5A00, 0X9AC1, 0X9B81, 0X5B40, 0X9901, 0X59C0, 0X5880, 0X9841, + 0X8801, 0X48C0, 0X4980, 0X8941, 0X4B00, 0X8BC1, 0X8A81, 0X4A40, + 0X4E00, 0X8EC1, 0X8F81, 0X4F40, 0X8D01, 0X4DC0, 0X4C80, 0X8C41, + 0X4400, 0X84C1, 0X8581, 0X4540, 0X8701, 0X47C0, 0X4680, 0X8641, + 0X8201, 0X42C0, 0X4380, 0X8341, 0X4100, 0X81C1, 0X8081, 0X4040 + }; + +unsigned int crc (byte* nData, unsigned int nLength){ + byte nTemp; + unsigned int wCRCWord = 0xFFFF; + + while (nLength--) + { + nTemp = *nData++ ^ wCRCWord; + wCRCWord >>= 8; + wCRCWord ^= TABLE[nTemp]; + } + return wCRCWord; + +} diff --git a/crc16_test/crc16.h b/crc16_test/crc16.h new file mode 100644 index 0000000..fb6bce5 --- /dev/null +++ b/crc16_test/crc16.h @@ -0,0 +1,8 @@ +#ifndef CRC16_h +#define CRC16_h + +#include "Arduino.h" + +unsigned int crc (byte* nData, unsigned int nLength); + +#endif diff --git a/crc16_test/crc16_test.ino b/crc16_test/crc16_test.ino new file mode 100644 index 0000000..8efa811 --- /dev/null +++ b/crc16_test/crc16_test.ino @@ -0,0 +1,19 @@ +# include "crc16.h" + +void setup() { + // put your setup code here, to run once: +Serial.begin(9600); +} + +void loop() { + byte array[] = {0x7e, 0x01, 0x01, 0x00, 0x00}; + unsigned int crc16 = crc(array, 3); + + byte high = highByte(crc16); + byte low = lowByte(crc16); + + Serial.print(crc16, HEX); Serial.print(" = "); + Serial.print(high, HEX); Serial.print(" "); + Serial.println(low, HEX); + delay(5000); +} diff --git a/data_types/.vscode/arduino.json b/data_types/.vscode/arduino.json new file mode 100644 index 0000000..c6e3edb --- /dev/null +++ b/data_types/.vscode/arduino.json @@ -0,0 +1,7 @@ +{ + "programmer": "AVRISP mkII", + "board": "arduino:avr:nano", + "configuration": "cpu=atmega328", + "port": "/dev/ttyUSB0", + "sketch": "test.ino" +} \ No newline at end of file diff --git a/data_types/.vscode/c_cpp_properties.json b/data_types/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..2472554 --- /dev/null +++ b/data_types/.vscode/c_cpp_properties.json @@ -0,0 +1,20 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "/home/elex/.arduino15/packages/arduino/tools/**", + "/home/elex/.arduino15/packages/arduino/hardware/avr/1.6.19/**", + "/home/elex/.arduino15/packages/arduino/hardware/avr/1.6.19/cores/arduino" + ], + "forcedInclude": [ + "/home/elex/.arduino15/packages/arduino/hardware/avr/1.6.19/cores/arduino/Arduino.h" + ], + "intelliSenseMode": "gcc-x64", + "compilerPath": "/usr/bin/gcc", + "cStandard": "c11", + "cppStandard": "c++17" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/data_types/.vscode/ipch/8711c00ae1e7926b/datatypes.ipch b/data_types/.vscode/ipch/8711c00ae1e7926b/datatypes.ipch new file mode 100644 index 0000000..48cb3f6 Binary files /dev/null and b/data_types/.vscode/ipch/8711c00ae1e7926b/datatypes.ipch differ diff --git a/data_types/.vscode/ipch/8711c00ae1e7926b/mmap_address.bin b/data_types/.vscode/ipch/8711c00ae1e7926b/mmap_address.bin new file mode 100644 index 0000000..773b3e0 Binary files /dev/null and b/data_types/.vscode/ipch/8711c00ae1e7926b/mmap_address.bin differ diff --git a/data_types/.vscode/ipch/9ac9eb7d397865bd/mmap_address.bin b/data_types/.vscode/ipch/9ac9eb7d397865bd/mmap_address.bin new file mode 100644 index 0000000..7233a13 Binary files /dev/null and b/data_types/.vscode/ipch/9ac9eb7d397865bd/mmap_address.bin differ diff --git a/data_types/.vscode/ipch/9ac9eb7d397865bd/test.ipch b/data_types/.vscode/ipch/9ac9eb7d397865bd/test.ipch new file mode 100644 index 0000000..eebd988 Binary files /dev/null and b/data_types/.vscode/ipch/9ac9eb7d397865bd/test.ipch differ diff --git a/data_types/data_types.ino b/data_types/data_types.ino new file mode 100644 index 0000000..5023c8b --- /dev/null +++ b/data_types/data_types.ino @@ -0,0 +1,86 @@ +#include "datatypes.h" + +void setup() { + // start serial port at 9600 bps: + Serial.begin(9600); + +} + +void loop() { + Int1 i1; + i1.value = 255; + print_test("Int1", toHexString(i1), toString(i1), sizeof(i1)); + + UInt1 u1; + u1.value = 255; + print_test("UInt1", toHexString(u1), toString(u1), sizeof(u1)); + + + Int2 i2; + i2.value = -5536; + print_test("Int2", toHexString(i2), toString(i2), sizeof(i2)); + + UInt2 u2; + u2.value = 60000; + print_test("UInt2", toHexString(u2), toString(u2), sizeof(u2)); + + + Int4 i4; + i4.value = 0xf0e0d0c0; + print_test("Int4", toHexString(i4), toString(i4), sizeof(i4)); + + UInt4 u4; + u4.value = 0xf0e0d0c0; + print_test("UInt4", toHexString(u4), toString(u4), sizeof(u4)); + + + Int8 i8 = new_Int8(500); + print_test("Int8", toHexString(i8), toString(i8), sizeof(i8)); + i8.value = 0xF0000000F0E0D0C0; + print_test("Int8", toHexString(i8), toString(i8), sizeof(i8)); + + UInt8 u8; + u8.value = 0xF0000000F0E0D0C0; + u8.value *= 300; + print_test("UInt8", toHexString(u8), toString(u8), sizeof(u8)); + + + Float4 f4; + f4.value = 3.141592; + print_test("Float4", toHexString(f4), toString(f4), sizeof(f4)); + + + /* + * double -> float + */ + byte ieee[8] = { // 3.141592 + 0x40, 0x09, 0x21, 0xfa, 0xfc, 0x8b, 0x00, 0x7a + }; + f4 = conv_double_to_float(ieee); + print_test("Double -> Float4", toHexString(f4), toString(f4), sizeof(f4)); + + i2 = new_Int2(ieee, 2); // 0x21fa + print_test("Int2 from byte[]", toHexString(i2), toString(i2), sizeof(i2)); + + /* + * Operator + */ + Int1 _i1; + _i1.value = -100; + i1 = i1+_i1; + print_test("Int1 + Int1", toHexString(i1), toString(i1), sizeof(i1)); + + i2 = 10+i1+100; + print_test("Int1 + int", toHexString(i2), toString(i2), sizeof(i2)); + + //Serial.println(crc(ieee, 2)); + //Int8 as = new_Int8(500); + + delay(5000); +} + +void print_test(String tag, String hexStr, String val, int size){ + Serial.print(tag); Serial.print(" ("); Serial.print(size); Serial.print(")\n"); + Serial.print("\t"); Serial.print(hexStr); Serial.print("\t"); Serial.print(val); + Serial.println("\n"); +} diff --git a/data_types/datatypes.cpp b/data_types/datatypes.cpp new file mode 100644 index 0000000..1543398 --- /dev/null +++ b/data_types/datatypes.cpp @@ -0,0 +1,509 @@ +#include "Arduino.h" +#include "datatypes.h" + +#define INT8_CHAR_BUFF_SIZE 21 +#define DECIMAL_PLACE 6 + +/* + 바이트 배열을 역순으로 +*/ +void array_reverse(byte array[], unsigned int len, byte result[]){ + for (int i=0; i> 4) & 0x0F; + byte nib2 = (array[i] >> 0) & 0x0F; + result[i * 2 + 0] = nib1 < 0xA ? '0' + nib1 : 'A' + nib1 - 0xA; + result[i * 2 + 1] = nib2 < 0xA ? '0' + nib2 : 'A' + nib2 - 0xA; + } + result[len * 2] = '\0'; + return String(result); +} + +/* + * IEEE double procision을 single precision으로 변환. + * + * https://github.com/RobTillaart/Arduino/blob/master/libraries/IEEE754tools/IEEE754tools.h + */ +Float4 conv_double_to_float(byte array[]){ + Float4 fl; + Float8 dbl; + + for (int i=0; i<8; i++){ + //dbl.bytes[i] = array[i]; + dbl.bytes[i] = array[7-i]; + } + + int exponent = dbl.p.exponent-1023 +127; // exponent adjust + // TODO check exponent overflow. + if (exponent >=0 || exponent <= 255) { + fl.p.sign = dbl.p.sign; + fl.p.exponent = exponent; + fl.p.mentissa = dbl.p.mentissa; // note this one clips the mantisse + return fl; + } + return fl; // error +} + +Float4 conv_double_to_float(Float8 val){ + byte temp[8]; + array_reverse(val.bytes, 8, temp); + return conv_double_to_float(temp); +} + +// to String ===================================================================== + +String toString(Int1 value){ + return String((int)value.value); +} + +String toString(UInt1 value){ + return String(value.value); +} + +String toString(Int2 value){ + return String(value.value); +} + +String toString(UInt2 value){ + return String(value.value); +} + +String toString(Int4 value){ + return String(value.value); +} + +String toString(UInt4 value){ + return String(value.value); +} + +String toString(Int8 value){ + int m; + int i=0; + long long tmp = value.value; + char buff[INT8_CHAR_BUFF_SIZE], rev_buff[INT8_CHAR_BUFF_SIZE]; + bool isMinus = tmp<0; + if (isMinus){ + // 값이 음수인 경우, + // 문자열에 부호를 추가하고, -1을 곱해서 양수로 만든 다음 나머지 작업을 한다. + // 부호 추가는 맨 뒤에. + tmp *=-1; + } + while (tmp/10>0) { + m = tmp%10; + buff[i]=(char)(m+0x30); + tmp /= 10; + i++; + } + buff[i]=(char)(tmp+0x30); + if (isMinus){ + i++; + buff[i] = '-'; // 부호를 추가 + } + //buff[i+1] = '\0'; + + //char arr[i+1]; + char_array_reverse(buff, i+1, rev_buff); + rev_buff[i+1] = '\0'; + return String(rev_buff); +} + +String toString(UInt8 value){ + int m; + int i=0; + unsigned long long tmp = value.value; + char buff[INT8_CHAR_BUFF_SIZE], rev_buff[INT8_CHAR_BUFF_SIZE]; + while (tmp/10>0) { + m = tmp%10; + buff[i]=(char)(m+0x30); + tmp /= 10; + i++; + } + buff[i]=(char)(tmp+0x30); + //buff[i+1] = '\0'; + + //char arr[i+1]; + char_array_reverse(buff, i+1, rev_buff); + rev_buff[i+1] = '\0'; + return String(rev_buff); +} + +String toString(Float4 value){ + return toString(value, DECIMAL_PLACE); +} + +String toString(Float4 value, int decimalPlace){ + return String(value.value, decimalPlace); +} + +//String toString(Float8 value){ +// return toString(value, DECIMAL_PLACE); +//} + +//String toString(Float8 value, int decimalPlace){ +// return String(value.value, decimalPlace); +//} + +// to HEX String =============================================================================== + +String toHexString(Int1 value){ + return array_to_string(value.bytes, 1); +} + +String toHexString(UInt1 value){ + return array_to_string(value.bytes, 1); +} + +String toHexString(Int2 value){ + byte rev_arr[2]; + array_reverse(value.bytes, 2, rev_arr); + return array_to_string(rev_arr, 2); +} + +String toHexString(UInt2 value){ + byte rev_arr[2]; + array_reverse(value.bytes, 2, rev_arr); + return array_to_string(rev_arr, 2); +} + +String toHexString(Int4 value){ + byte rev_arr[4]; + array_reverse(value.bytes, 4, rev_arr); + return array_to_string(rev_arr, 4); +} + +String toHexString(UInt4 value){ + byte rev_arr[4]; + array_reverse(value.bytes, 4, rev_arr); + return array_to_string(rev_arr, 4); +} + +String toHexString(Int8 value){ + byte rev_arr[8]; + array_reverse(value.bytes, 8, rev_arr); + return array_to_string(rev_arr, 8); +} + +String toHexString(UInt8 value){ + byte rev_arr[8]; + array_reverse(value.bytes, 8, rev_arr); + return array_to_string(rev_arr, 8); +} + +String toHexString(Float4 value){ + byte rev_arr[4]; + array_reverse(value.bytes, 4, rev_arr); + return array_to_string(rev_arr, 4); +} + +//String toHexString(Float8 value){ +// byte rev_arr[8]; +// array_reverse(value.bytes, 8, rev_arr); +// return array_to_string(rev_arr, 8); +//} + +String toHexString(Int1 value, bool doNotRev){ + return toHexString(value); +} + +String toHexString(UInt1 value, bool doNotRev){ + return toHexString(value); +} + +String toHexString(Int2 value, bool doNotRev){ + if (doNotRev){ + return array_to_string(value.bytes, 2); + } else { + return toHexString(value); + } +} + +String toHexString(UInt2 value, bool doNotRev){ + if (doNotRev){ + return array_to_string(value.bytes, 2); + } else { + return toHexString(value); + } +} + +String toHexString(Int4 value, bool doNotRev){ + if (doNotRev){ + return array_to_string(value.bytes, 4); + } else { + return toHexString(value); + } +} + +String toHexString(UInt4 value, bool doNotRev){ + if (doNotRev){ + return array_to_string(value.bytes, 4); + } else { + return toHexString(value); + } +} + +String toHexString(Int8 value, bool doNotRev){ + if (doNotRev){ + return array_to_string(value.bytes, 8); + } else { + return toHexString(value); + } +} + +String toHexString(UInt8 value, bool doNotRev){ + if (doNotRev){ + return array_to_string(value.bytes, 8); + } else { + return toHexString(value); + } +} + +String toHexString(Float4 value, bool doNotRev){ + if (doNotRev){ + return array_to_string(value.bytes, 4); + } else { + return toHexString(value); + } +} + +//String toHexString(Float8 value, bool doNotRev){ +// if (doNotRev){ +// return array_to_string(value.bytes, 8); +// } else { +// return toHexString(value); +// } +//} + +// Constructors ========================================================================= +Int1 new_Int1(byte arr[]){ + return new_Int1(arr, 0); +} + +Int1 new_Int1(byte arr[], int startIdx){ + Int1 v; + v.bytes[0] = arr[startIdx]; + return v; +} + +UInt1 new_UInt1(byte arr[]){ + return new_UInt1(arr, 0); +} + +UInt1 new_UInt1(byte arr[], int startIdx){ + UInt1 v; + v.bytes[0] = arr[startIdx]; + return v; +} + +Int2 new_Int2(byte arr[]){ + return new_Int2(arr, 0); +} + +Int2 new_Int2(byte arr[], int startIdx){ + Int2 v; + for (int i=0; i<2; i++) { + v.bytes[i] = arr[startIdx + 2-1-i]; + } + return v; +} + +UInt2 new_UInt2(byte arr[]){ + return new_UInt2(arr, 0); +} + +UInt2 new_UInt2(byte arr[], int startIdx){ + UInt2 v; + for (int i=0; i<2; i++) { + v.bytes[i] = arr[startIdx + 2-1-i]; + } + return v; +} + +Int4 new_Int4(byte arr[]){ + return new_Int4(arr, 0); +} + +Int4 new_Int4(byte arr[], int startIdx){ + Int4 v; + for (int i=0; i<4; i++) { + v.bytes[i] = arr[startIdx + 4-1-i]; + } + return v; +} + +UInt4 new_UInt4(byte arr[]){ + return new_UInt4(arr, 0); +} + +UInt4 new_UInt4(byte arr[], int startIdx){ + UInt4 v; + for (int i=0; i<4; i++) { + v.bytes[i] = arr[startIdx + 4-1-i]; + } + return v; +} + +Int8 new_Int8(byte arr[]){ + return new_Int8(arr, 0); +} + +Int8 new_Int8(byte arr[], int startIdx){ + Int8 v; + for (int i=0; i<8; i++) { + v.bytes[i] = arr[startIdx + 8-1-i]; + } + return v; +} + +UInt8 new_UInt8(byte arr[]){ + return new_UInt8(arr, 0); +} + +UInt8 new_UInt8(byte arr[], int startIdx){ + UInt8 v; + for (int i=0; i<8; i++) { + v.bytes[i] = arr[startIdx + 8-1-i]; + } + return v; +} + +Float4 new_Float4(byte arr[]){ + return new_Float4(arr, 0); +} + +Float4 new_Float4(byte arr[], int startIdx){ + Float4 v; + for (int i=0; i<4; i++) { + v.bytes[i] = arr[startIdx + 4-1-i]; + } + return v; +} + +Float8 new_Float8(byte arr[]){ + return new_Float8(arr, 0); +} + +Float8 new_Float8(byte arr[], int startIdx){ + Float8 v; + for (int i=0; i<8; i++) { + v.bytes[i] = arr[startIdx + 8-1-i]; + } + return v; +} + +Int1 new_Int1(char val){ + Int1 v; + v.value = val; + return v; +} + +Int2 new_Int2(int val){ + Int2 v; + v.value = val; + return v; +} + +Int4 new_Int4(long val){ + Int4 v; + v.value = val; + return v; +} + +Int8 new_Int8(long long val){ + Int8 v; + v.value = val; + return v; +} + +UInt1 new_UInt1(byte val){ + UInt1 v; + v.value = val; + return v; +} + +UInt2 new_UInt2(unsigned int val){ + UInt2 v; + v.value = val; + return v; +} + +UInt4 new_UInt4(unsigned long val){ + UInt4 v; + v.value = val; + return v; +} + +UInt8 new_UInt8(unsigned long long val){ + UInt8 v; + v.value = val; + return v; +} + +Float4 new_Float4(float val){ + Float4 v; + v.value = val; + return v; +} + +//Float8 new_Float8(double val){ +// Float8 v; +// v.value = val; +// return v; +//} + +// 연산자 오버로딩 ======================================================================== + +Int1 operator+(const Int1& a, const Int1& b){ + Int1 val; + val.value = a.value + b.value; + return val; +} + +Int2 operator+(const Int1& a, const int b){ + Int2 val; + val.value = a.value + b; + return val; +} + +Int2 operator+(const int a, const Int1& b){ + Int2 val; + val.value = a + b.value; + return val; +} + +Int2 operator+(const Int2& a, const Int2& b){ + Int2 val; + val.value = a.value + b.value; + return val; +} + +Int2 operator+(const Int2& a, const int b){ + Int2 val; + val.value = a.value + b; + return val; +} + +Int2 operator+(const int a, const Int2& b){ + Int2 val; + val.value = a + b.value; + return val; +} diff --git a/data_types/datatypes.h b/data_types/datatypes.h new file mode 100644 index 0000000..b656ee3 --- /dev/null +++ b/data_types/datatypes.h @@ -0,0 +1,266 @@ +#ifndef DataTypes_h +#define DataTypes_h +#include "Arduino.h" + +#define INT1_MAX = 0x7f; +#define INT1_MIN = 0x80; +#define UINT1_MAX = 0xff; +#define UINT1_MIN = 0x00; + +#define INT2_MAX = 0x7fff; +#define INT2_MIN = 0x8000; +#define UINT2_MAX = 0xffff; +#define UINT2_MIN = 0x0000; + +#define INT4_MAX = 0x7fffffffL; +#define INT4_MIN = 0x80000000L; +#define UINT4_MAX = 0xffffffffL; +#define UINT4_MIN = 0x00000000L; + +#define INT8_MAX = 0x7fffffffffffffffLL; +#define INT8_MIN = 0x8000000000000000LL; +#define UINT8_MIN = 0xffffffffffffffffULL; +#define UINT8_MIN = 0x0000000000000000ULL; + +/* + * IEEE754 float layout; + * + * Single Precision + * 부호 : 1 bit + * 지수(exponent) : 8 bit + * 가수(mentissa) : 23 bit + */ +struct IEEEsingle{ + uint32_t mentissa:23; + uint8_t exponent:8; + uint8_t sign:1; +}; + +// IEEE754 double layout; +struct IEEEdouble { + uint32_t filler:29; // it is only able to map 23 bits of the mantisse a filler is added for the remaining bits. + uint32_t mentissa:23; + uint16_t exponent:11; + uint8_t sign:1; +}; + +/** + * + * 자료형 ============================================================================== + * + * 연산을 할 때에는 value를 사용. + * 바이트 배열을 처리할 때에는 bytes를 사용. + * bytes는 LowByte가 먼저이므로 주의. + * + * TODO + * 클래스로 처리하고, 상속 구조로 바꾸면 더 편해질 것 같지만, C++ 쓸 줄 모름. + * 연산자 오버로딩의 경우에도 쉬운 방법이 있을 것 같지만, 능력 부족. + * + */ +typedef union Int8 { + byte bytes[8]; + long long value; +} Int8; + +typedef union UInt8 { + byte bytes[8]; + unsigned long long value; +} UInt8; + +typedef union Int4 { + byte bytes[4]; + long value; +} Int4; + +typedef union UInt4 { + byte bytes[4]; + unsigned long value; +} UInt4; + +typedef union Int2 { + byte bytes[2]; + int value; +} Int2; + +typedef union UInt2 { + byte bytes[2]; + unsigned int value; +} UInt2; + +typedef union Int1 { + byte bytes[1]; + char value; +} Int1; + +typedef union UInt1 { + byte bytes[1]; + byte value; +} UInt1; + + +typedef union Float4 { + byte bytes[4]; + float value; // 4 bytes + IEEEsingle p; +} Float4; + +typedef union Float8 { // double->float 변환용으로만 사용한다. + byte bytes[8]; + double value; // 4 bytes + IEEEdouble p; +} Float8; + +/** + * + * Constructors ========================================================== + * + */ + +Int1 new_Int1(char val); +Int2 new_Int2(int val); +Int4 new_Int4(long val); +Int8 new_Int8(long long val); + +UInt1 new_UInt1(byte val); +UInt2 new_UInt2(unsigned int val); +UInt4 new_UInt4(unsigned long val); +UInt8 new_UInt8(unsigned long long val); + +Float4 new_Float4(float val); +//Float8 new_Float8(double val); + +Int1 new_Int1(byte arr[]); +Int2 new_Int2(byte arr[]); +Int4 new_Int4(byte arr[]); +Int8 new_Int8(byte arr[]); + +/* + * arr : 맨 왼쪽부터 순서대로라고 가정한다. + * startIdx : arr 배열에서 값을 읽어올 시작 위치 인덱스 + */ +Int1 new_Int1(byte arr[], int startIdx); +Int2 new_Int2(byte arr[], int startIdx); +Int4 new_Int4(byte arr[], int startIdx); +Int8 new_Int8(byte arr[], int startIdx); + +UInt1 new_UInt1(byte arr[]); +UInt2 new_UInt2(byte arr[]); +UInt4 new_UInt4(byte arr[]); +UInt8 new_UInt8(byte arr[]); + +UInt1 new_UInt1(byte arr[], int startIdx); +UInt2 new_UInt2(byte arr[], int startIdx); +UInt4 new_UInt4(byte arr[], int startIdx); +UInt8 new_UInt8(byte arr[], int startIdx); + +Float4 new_Float4(byte arr[]); +Float8 new_Float8(byte arr[]); + +Float4 new_Float4(byte arr[], int startIdx); +Float8 new_Float8(byte arr[], int startIdx); + +/* + * IEEE754 배정도 부동소수를 단정도 부동소수로 변환. + * + * array : IEEE 배정도 부동소수 (8바이트). + * 부호비트가 맨 왼쪽에 있다고 본다. 아니라면, 뒤집어서 입력할 것. + */ +Float4 conv_double_to_float(byte array[]); +Float4 conv_double_to_float(Float8 val); + +/** + * + * Operators ======================================================================== + * + * 경우의 수가 너무 많으므로 필요할 때마다 추가해야할 듯. + * template 같은 걸 쓰면 될 것 같은데, 어떻게 쓰는건지 모르겠음. + * 또는, .value를 사용해서 연산하는데 편할 듯. + */ + +Int1 operator+(const Int1& a, const Int1& b); +Int2 operator+(const Int1& a, const int b); +Int2 operator+(const int a, const Int1& b); +Int2 operator+(const Int2& a, const Int2& b); +Int2 operator+(const Int2& a, const int b); +Int2 operator+(const int a, const Int2& b); + +/** + * + * To HEX String ====================================================== + * + */ + +// HighByte가 먼저 출력됨. +String toHexString(Int1 value); +String toHexString(Int2 value); +String toHexString(Int4 value); +String toHexString(Int8 value); + +String toHexString(UInt1 value); +String toHexString(UInt2 value); +String toHexString(UInt4 value); +String toHexString(UInt8 value); + +String toHexString(Float4 value); +//String toHexString(Float8 value); + +// doNotRev : true이면 LowByte가 먼저 출력됨. +String toHexString(Int1 value, bool doNotRev); +String toHexString(Int2 value, bool doNotRev); +String toHexString(Int4 value, bool doNotRev); +String toHexString(Int8 value, bool doNotRev); + +String toHexString(UInt1 value, bool doNotRev); +String toHexString(UInt2 value, bool doNotRev); +String toHexString(UInt4 value, bool doNotRev); +String toHexString(UInt8 value, bool doNotRev); + +String toHexString(Float4 value, bool doNotRev); +//String toHexString(Float8 value, bool doNotRev); + +/** + * + * To String ====================================================== + * + */ + +String toString(Int1 value); +String toString(Int2 value); +String toString(Int4 value); +String toString(Int8 value); + +String toString(UInt1 value); +String toString(UInt2 value); +String toString(UInt4 value); +String toString(UInt8 value); + +/* + decimalPlace : 소수점 이하 자릿수 + */ +String toString(Float4 value, int decimalPlace); +String toString(Float4 value); +//String toString(Float8 value, int decimalPlace); +//String toString(Float8 value); + +/** + * + * Utilities ====================================================== + * + */ + +/* + 바이트 배열을 16진수 문자열로. + array : 원본 배열 + len : 배열 길이 +*/ +String array_to_string(byte array[], unsigned int len); + +/* + 바이트 배열의 순서를 뒤집기. + array : 원본 배열 + len : 배열 길이 + result : 뒤집힌 배열이 저장될 새로운 배열 +*/ +void array_reverse(byte array[], unsigned int len, byte result[]); + +#endif