trilogy 2.4.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +14 -5
- data/Rakefile +6 -0
- data/ext/trilogy-ruby/cast.c +0 -4
- data/ext/trilogy-ruby/cext.c +106 -34
- data/ext/trilogy-ruby/inc/trilogy/blocking.h +118 -0
- data/ext/trilogy-ruby/inc/trilogy/builder.h +60 -0
- data/ext/trilogy-ruby/inc/trilogy/client.h +214 -0
- data/ext/trilogy-ruby/inc/trilogy/error.h +4 -1
- data/ext/trilogy-ruby/inc/trilogy/protocol.h +269 -3
- data/ext/trilogy-ruby/inc/trilogy/reader.h +4 -0
- data/ext/trilogy-ruby/inc/trilogy/socket.h +2 -1
- data/ext/trilogy-ruby/src/blocking.c +117 -0
- data/ext/trilogy-ruby/src/builder.c +63 -0
- data/ext/trilogy-ruby/src/client.c +180 -17
- data/ext/trilogy-ruby/src/protocol.c +503 -0
- data/ext/trilogy-ruby/src/reader.c +38 -0
- data/ext/trilogy-ruby/src/socket.c +96 -39
- data/lib/trilogy/encoding.rb +97 -0
- data/lib/trilogy/error.rb +118 -0
- data/lib/trilogy/result.rb +33 -0
- data/lib/trilogy/version.rb +1 -1
- data/lib/trilogy.rb +9 -239
- data/trilogy.gemspec +1 -1
- metadata +6 -3
@@ -12,6 +12,12 @@
|
|
12
12
|
#define TRILOGY_CMD_PING 0x0e
|
13
13
|
#define TRILOGY_CMD_SET_OPTION 0x1b
|
14
14
|
|
15
|
+
#define TRILOGY_CMD_STMT_PREPARE 0x16
|
16
|
+
#define TRILOGY_CMD_STMT_EXECUTE 0x17
|
17
|
+
#define TRILOGY_CMD_STMT_SEND_LONG_DATA 0x18
|
18
|
+
#define TRILOGY_CMD_STMT_CLOSE 0x19
|
19
|
+
#define TRILOGY_CMD_STMT_RESET 0x1a
|
20
|
+
|
15
21
|
#define SCRAMBLE_LEN 20
|
16
22
|
|
17
23
|
static size_t min(size_t a, size_t b)
|
@@ -395,6 +401,37 @@ fail:
|
|
395
401
|
return rc;
|
396
402
|
}
|
397
403
|
|
404
|
+
int trilogy_parse_stmt_ok_packet(const uint8_t *buff, size_t len, trilogy_stmt_ok_packet_t *out_packet)
|
405
|
+
{
|
406
|
+
int rc;
|
407
|
+
|
408
|
+
trilogy_reader_t reader = TRILOGY_READER(buff, len);
|
409
|
+
|
410
|
+
// skip packet type
|
411
|
+
CHECKED(trilogy_reader_get_uint8(&reader, NULL));
|
412
|
+
|
413
|
+
CHECKED(trilogy_reader_get_uint32(&reader, &out_packet->id));
|
414
|
+
|
415
|
+
CHECKED(trilogy_reader_get_uint16(&reader, &out_packet->column_count));
|
416
|
+
|
417
|
+
CHECKED(trilogy_reader_get_uint16(&reader, &out_packet->parameter_count));
|
418
|
+
|
419
|
+
uint8_t filler;
|
420
|
+
|
421
|
+
CHECKED(trilogy_reader_get_uint8(&reader, &filler));
|
422
|
+
|
423
|
+
if (filler != 0) {
|
424
|
+
return TRILOGY_PROTOCOL_VIOLATION;
|
425
|
+
}
|
426
|
+
|
427
|
+
CHECKED(trilogy_reader_get_uint16(&reader, &out_packet->warning_count));
|
428
|
+
|
429
|
+
return trilogy_reader_finish(&reader);
|
430
|
+
|
431
|
+
fail:
|
432
|
+
return rc;
|
433
|
+
}
|
434
|
+
|
398
435
|
static void trilogy_pack_scramble_native_hash(const char *scramble, const char *password, size_t password_len,
|
399
436
|
uint8_t *buffer, unsigned int *buffer_len)
|
400
437
|
{
|
@@ -683,4 +720,470 @@ fail:
|
|
683
720
|
return rc;
|
684
721
|
}
|
685
722
|
|
723
|
+
int trilogy_build_stmt_prepare_packet(trilogy_builder_t *builder, const char *sql, size_t sql_len)
|
724
|
+
{
|
725
|
+
int rc = TRILOGY_OK;
|
726
|
+
|
727
|
+
CHECKED(trilogy_builder_write_uint8(builder, TRILOGY_CMD_STMT_PREPARE));
|
728
|
+
|
729
|
+
CHECKED(trilogy_builder_write_buffer(builder, sql, sql_len));
|
730
|
+
|
731
|
+
trilogy_builder_finalize(builder);
|
732
|
+
|
733
|
+
return TRILOGY_OK;
|
734
|
+
|
735
|
+
fail:
|
736
|
+
return rc;
|
737
|
+
}
|
738
|
+
|
739
|
+
int trilogy_build_stmt_execute_packet(trilogy_builder_t *builder, uint32_t stmt_id, uint8_t flags,
|
740
|
+
trilogy_binary_value_t *binds, uint16_t num_binds)
|
741
|
+
{
|
742
|
+
int rc = TRILOGY_OK;
|
743
|
+
|
744
|
+
CHECKED(trilogy_builder_write_uint8(builder, TRILOGY_CMD_STMT_EXECUTE));
|
745
|
+
|
746
|
+
CHECKED(trilogy_builder_write_uint32(builder, stmt_id));
|
747
|
+
|
748
|
+
CHECKED(trilogy_builder_write_uint8(builder, flags));
|
749
|
+
|
750
|
+
// apparently, iteration-count is always 1
|
751
|
+
CHECKED(trilogy_builder_write_uint32(builder, 1));
|
752
|
+
|
753
|
+
int i;
|
754
|
+
|
755
|
+
if (num_binds > 0) {
|
756
|
+
if (binds == NULL) {
|
757
|
+
return TRILOGY_PROTOCOL_VIOLATION;
|
758
|
+
}
|
759
|
+
|
760
|
+
uint8_t current_bits = 0;
|
761
|
+
|
762
|
+
for (i = 0; i < num_binds; i++) {
|
763
|
+
if (binds[i].is_null) {
|
764
|
+
current_bits |= 1 << (i % 8);
|
765
|
+
}
|
766
|
+
|
767
|
+
// If we hit a byte boundary, write the bits we have so far and continue
|
768
|
+
if ((i % 8) == 7) {
|
769
|
+
CHECKED(trilogy_builder_write_uint8(builder, current_bits))
|
770
|
+
|
771
|
+
current_bits = 0;
|
772
|
+
}
|
773
|
+
}
|
774
|
+
|
775
|
+
// If there would have been any remainder bits, finally write those as well
|
776
|
+
if (num_binds % 8) {
|
777
|
+
CHECKED(trilogy_builder_write_uint8(builder, current_bits))
|
778
|
+
}
|
779
|
+
|
780
|
+
// new params bound flag
|
781
|
+
CHECKED(trilogy_builder_write_uint8(builder, 0x1));
|
782
|
+
|
783
|
+
for (i = 0; i < num_binds; i++) {
|
784
|
+
CHECKED(trilogy_builder_write_uint8(builder, binds[i].type));
|
785
|
+
|
786
|
+
if (binds[i].is_unsigned) {
|
787
|
+
CHECKED(trilogy_builder_write_uint8(builder, 0x80));
|
788
|
+
} else {
|
789
|
+
CHECKED(trilogy_builder_write_uint8(builder, 0x00));
|
790
|
+
}
|
791
|
+
}
|
792
|
+
|
793
|
+
for (i = 0; i < num_binds; i++) {
|
794
|
+
trilogy_binary_value_t val = binds[i];
|
795
|
+
|
796
|
+
switch (val.type) {
|
797
|
+
case TRILOGY_TYPE_TINY:
|
798
|
+
CHECKED(trilogy_builder_write_uint8(builder, val.as.uint8));
|
799
|
+
|
800
|
+
break;
|
801
|
+
case TRILOGY_TYPE_SHORT:
|
802
|
+
CHECKED(trilogy_builder_write_uint16(builder, val.as.uint16));
|
803
|
+
|
804
|
+
break;
|
805
|
+
case TRILOGY_TYPE_INT24:
|
806
|
+
case TRILOGY_TYPE_LONG:
|
807
|
+
CHECKED(trilogy_builder_write_uint32(builder, val.as.uint32));
|
808
|
+
|
809
|
+
break;
|
810
|
+
case TRILOGY_TYPE_LONGLONG:
|
811
|
+
CHECKED(trilogy_builder_write_uint64(builder, val.as.uint64));
|
812
|
+
|
813
|
+
break;
|
814
|
+
case TRILOGY_TYPE_FLOAT:
|
815
|
+
CHECKED(trilogy_builder_write_float(builder, val.as.flt));
|
816
|
+
|
817
|
+
break;
|
818
|
+
case TRILOGY_TYPE_DOUBLE:
|
819
|
+
CHECKED(trilogy_builder_write_double(builder, val.as.dbl));
|
820
|
+
|
821
|
+
break;
|
822
|
+
case TRILOGY_TYPE_YEAR:
|
823
|
+
CHECKED(trilogy_builder_write_uint16(builder, val.as.year));
|
824
|
+
|
825
|
+
break;
|
826
|
+
case TRILOGY_TYPE_TIME: {
|
827
|
+
uint8_t field_len = 0;
|
828
|
+
|
829
|
+
if (val.as.time.micro_seconds) {
|
830
|
+
field_len = 12;
|
831
|
+
} else if (val.as.time.hour || val.as.time.minute || val.as.time.second) {
|
832
|
+
field_len = 8;
|
833
|
+
} else {
|
834
|
+
field_len = 0;
|
835
|
+
}
|
836
|
+
|
837
|
+
CHECKED(trilogy_builder_write_uint8(builder, field_len));
|
838
|
+
|
839
|
+
if (field_len > 0) {
|
840
|
+
CHECKED(trilogy_builder_write_uint8(builder, val.as.time.is_negative));
|
841
|
+
|
842
|
+
CHECKED(trilogy_builder_write_uint32(builder, val.as.time.days));
|
843
|
+
|
844
|
+
CHECKED(trilogy_builder_write_uint8(builder, val.as.time.hour));
|
845
|
+
|
846
|
+
CHECKED(trilogy_builder_write_uint8(builder, val.as.time.minute));
|
847
|
+
|
848
|
+
CHECKED(trilogy_builder_write_uint8(builder, val.as.time.second));
|
849
|
+
|
850
|
+
if (field_len > 8) {
|
851
|
+
CHECKED(trilogy_builder_write_uint32(builder, val.as.time.micro_seconds));
|
852
|
+
}
|
853
|
+
}
|
854
|
+
|
855
|
+
break;
|
856
|
+
}
|
857
|
+
case TRILOGY_TYPE_DATE:
|
858
|
+
case TRILOGY_TYPE_DATETIME:
|
859
|
+
case TRILOGY_TYPE_TIMESTAMP: {
|
860
|
+
uint8_t field_len = 0;
|
861
|
+
|
862
|
+
if (val.as.date.datetime.micro_seconds) {
|
863
|
+
field_len = 11;
|
864
|
+
} else if (val.as.date.datetime.hour || val.as.date.datetime.minute || val.as.date.datetime.second) {
|
865
|
+
field_len = 7;
|
866
|
+
} else if (val.as.date.year || val.as.date.month || val.as.date.day) {
|
867
|
+
field_len = 4;
|
868
|
+
} else {
|
869
|
+
field_len = 0;
|
870
|
+
}
|
871
|
+
|
872
|
+
CHECKED(trilogy_builder_write_uint8(builder, field_len));
|
873
|
+
|
874
|
+
if (field_len > 0) {
|
875
|
+
CHECKED(trilogy_builder_write_uint16(builder, val.as.date.year));
|
876
|
+
|
877
|
+
CHECKED(trilogy_builder_write_uint8(builder, val.as.date.month));
|
878
|
+
|
879
|
+
CHECKED(trilogy_builder_write_uint8(builder, val.as.date.day));
|
880
|
+
|
881
|
+
if (field_len > 4) {
|
882
|
+
CHECKED(trilogy_builder_write_uint8(builder, val.as.date.datetime.hour));
|
883
|
+
|
884
|
+
CHECKED(trilogy_builder_write_uint8(builder, val.as.date.datetime.minute));
|
885
|
+
|
886
|
+
CHECKED(trilogy_builder_write_uint8(builder, val.as.date.datetime.second));
|
887
|
+
|
888
|
+
if (field_len > 7) {
|
889
|
+
CHECKED(trilogy_builder_write_uint32(builder, val.as.date.datetime.micro_seconds));
|
890
|
+
}
|
891
|
+
}
|
892
|
+
}
|
893
|
+
|
894
|
+
break;
|
895
|
+
}
|
896
|
+
case TRILOGY_TYPE_DECIMAL:
|
897
|
+
case TRILOGY_TYPE_VARCHAR:
|
898
|
+
case TRILOGY_TYPE_BIT:
|
899
|
+
case TRILOGY_TYPE_NEWDECIMAL:
|
900
|
+
case TRILOGY_TYPE_ENUM:
|
901
|
+
case TRILOGY_TYPE_SET:
|
902
|
+
case TRILOGY_TYPE_TINY_BLOB:
|
903
|
+
case TRILOGY_TYPE_BLOB:
|
904
|
+
case TRILOGY_TYPE_MEDIUM_BLOB:
|
905
|
+
case TRILOGY_TYPE_LONG_BLOB:
|
906
|
+
case TRILOGY_TYPE_VAR_STRING:
|
907
|
+
case TRILOGY_TYPE_STRING:
|
908
|
+
case TRILOGY_TYPE_GEOMETRY:
|
909
|
+
CHECKED(trilogy_builder_write_lenenc_buffer(builder, val.as.str.data, val.as.str.len));
|
910
|
+
|
911
|
+
break;
|
912
|
+
case TRILOGY_TYPE_NULL:
|
913
|
+
// already handled by the null bitmap
|
914
|
+
break;
|
915
|
+
default:
|
916
|
+
return TRILOGY_UNKNOWN_TYPE;
|
917
|
+
}
|
918
|
+
}
|
919
|
+
}
|
920
|
+
|
921
|
+
trilogy_builder_finalize(builder);
|
922
|
+
|
923
|
+
return TRILOGY_OK;
|
924
|
+
|
925
|
+
fail:
|
926
|
+
return rc;
|
927
|
+
}
|
928
|
+
|
929
|
+
int trilogy_build_stmt_bind_data_packet(trilogy_builder_t *builder, uint32_t stmt_id, uint16_t param_id, uint8_t *data,
|
930
|
+
size_t data_len)
|
931
|
+
{
|
932
|
+
int rc = TRILOGY_OK;
|
933
|
+
|
934
|
+
CHECKED(trilogy_builder_write_uint8(builder, TRILOGY_CMD_STMT_SEND_LONG_DATA));
|
935
|
+
|
936
|
+
CHECKED(trilogy_builder_write_uint32(builder, stmt_id));
|
937
|
+
|
938
|
+
CHECKED(trilogy_builder_write_uint16(builder, param_id));
|
939
|
+
|
940
|
+
CHECKED(trilogy_builder_write_buffer(builder, data, data_len));
|
941
|
+
|
942
|
+
trilogy_builder_finalize(builder);
|
943
|
+
|
944
|
+
return TRILOGY_OK;
|
945
|
+
|
946
|
+
fail:
|
947
|
+
return rc;
|
948
|
+
}
|
949
|
+
|
950
|
+
int trilogy_build_stmt_reset_packet(trilogy_builder_t *builder, uint32_t stmt_id)
|
951
|
+
{
|
952
|
+
int rc = TRILOGY_OK;
|
953
|
+
|
954
|
+
CHECKED(trilogy_builder_write_uint8(builder, TRILOGY_CMD_STMT_RESET));
|
955
|
+
|
956
|
+
CHECKED(trilogy_builder_write_uint32(builder, stmt_id));
|
957
|
+
|
958
|
+
trilogy_builder_finalize(builder);
|
959
|
+
|
960
|
+
return TRILOGY_OK;
|
961
|
+
|
962
|
+
fail:
|
963
|
+
return rc;
|
964
|
+
}
|
965
|
+
|
966
|
+
int trilogy_build_stmt_close_packet(trilogy_builder_t *builder, uint32_t stmt_id)
|
967
|
+
{
|
968
|
+
int rc = TRILOGY_OK;
|
969
|
+
|
970
|
+
CHECKED(trilogy_builder_write_uint8(builder, TRILOGY_CMD_STMT_CLOSE));
|
971
|
+
|
972
|
+
CHECKED(trilogy_builder_write_uint32(builder, stmt_id));
|
973
|
+
|
974
|
+
trilogy_builder_finalize(builder);
|
975
|
+
|
976
|
+
return TRILOGY_OK;
|
977
|
+
|
978
|
+
fail:
|
979
|
+
return rc;
|
980
|
+
}
|
981
|
+
|
982
|
+
static inline int is_null(uint8_t *null_bitmap, uint64_t bitmap_len, uint64_t column_offset, bool *col_is_null)
|
983
|
+
{
|
984
|
+
if (column_offset > (bitmap_len * 8) - 1) {
|
985
|
+
return TRILOGY_PROTOCOL_VIOLATION;
|
986
|
+
}
|
987
|
+
|
988
|
+
column_offset += 2;
|
989
|
+
|
990
|
+
uint64_t byte_offset = column_offset / 8;
|
991
|
+
|
992
|
+
// for the binary protocol result row packet, we need to offset the bit check
|
993
|
+
// by 2
|
994
|
+
*col_is_null = (null_bitmap[byte_offset] & (1 << (column_offset % 8))) != 0;
|
995
|
+
|
996
|
+
return TRILOGY_OK;
|
997
|
+
}
|
998
|
+
|
999
|
+
int trilogy_parse_stmt_row_packet(const uint8_t *buff, size_t len, trilogy_column_packet_t *columns,
|
1000
|
+
uint64_t column_count, trilogy_binary_value_t *out_values)
|
1001
|
+
{
|
1002
|
+
int rc;
|
1003
|
+
|
1004
|
+
trilogy_reader_t reader = TRILOGY_READER(buff, len);
|
1005
|
+
|
1006
|
+
// skip packet header
|
1007
|
+
CHECKED(trilogy_reader_get_uint8(&reader, NULL));
|
1008
|
+
|
1009
|
+
uint8_t *null_bitmap = NULL;
|
1010
|
+
uint64_t bitmap_len = (column_count + 7 + 2) / 8;
|
1011
|
+
|
1012
|
+
CHECKED(trilogy_reader_get_buffer(&reader, bitmap_len, (const void **)&null_bitmap));
|
1013
|
+
|
1014
|
+
for (uint64_t i = 0; i < column_count; i++) {
|
1015
|
+
CHECKED(is_null(null_bitmap, bitmap_len, i, &out_values[i].is_null));
|
1016
|
+
if (out_values[i].is_null) {
|
1017
|
+
out_values[i].type = TRILOGY_TYPE_NULL;
|
1018
|
+
} else {
|
1019
|
+
out_values[i].is_null = false;
|
1020
|
+
|
1021
|
+
out_values[i].type = columns[i].type;
|
1022
|
+
|
1023
|
+
if (columns[i].flags & TRILOGY_COLUMN_FLAG_UNSIGNED) {
|
1024
|
+
out_values[i].is_unsigned = true;
|
1025
|
+
}
|
1026
|
+
|
1027
|
+
switch (columns[i].type) {
|
1028
|
+
case TRILOGY_TYPE_STRING:
|
1029
|
+
case TRILOGY_TYPE_VARCHAR:
|
1030
|
+
case TRILOGY_TYPE_VAR_STRING:
|
1031
|
+
case TRILOGY_TYPE_ENUM:
|
1032
|
+
case TRILOGY_TYPE_SET:
|
1033
|
+
case TRILOGY_TYPE_LONG_BLOB:
|
1034
|
+
case TRILOGY_TYPE_MEDIUM_BLOB:
|
1035
|
+
case TRILOGY_TYPE_BLOB:
|
1036
|
+
case TRILOGY_TYPE_TINY_BLOB:
|
1037
|
+
case TRILOGY_TYPE_GEOMETRY:
|
1038
|
+
case TRILOGY_TYPE_BIT:
|
1039
|
+
case TRILOGY_TYPE_DECIMAL:
|
1040
|
+
case TRILOGY_TYPE_NEWDECIMAL:
|
1041
|
+
case TRILOGY_TYPE_JSON:
|
1042
|
+
CHECKED(trilogy_reader_get_lenenc_buffer(&reader, &out_values[i].as.str.len,
|
1043
|
+
(const void **)&out_values[i].as.str.data));
|
1044
|
+
|
1045
|
+
break;
|
1046
|
+
case TRILOGY_TYPE_LONGLONG:
|
1047
|
+
CHECKED(trilogy_reader_get_uint64(&reader, &out_values[i].as.uint64));
|
1048
|
+
|
1049
|
+
break;
|
1050
|
+
case TRILOGY_TYPE_DOUBLE:
|
1051
|
+
CHECKED(trilogy_reader_get_double(&reader, &out_values[i].as.dbl));
|
1052
|
+
|
1053
|
+
break;
|
1054
|
+
case TRILOGY_TYPE_LONG:
|
1055
|
+
case TRILOGY_TYPE_INT24:
|
1056
|
+
CHECKED(trilogy_reader_get_uint32(&reader, &out_values[i].as.uint32));
|
1057
|
+
|
1058
|
+
break;
|
1059
|
+
case TRILOGY_TYPE_FLOAT:
|
1060
|
+
CHECKED(trilogy_reader_get_float(&reader, &out_values[i].as.flt));
|
1061
|
+
|
1062
|
+
break;
|
1063
|
+
case TRILOGY_TYPE_SHORT:
|
1064
|
+
CHECKED(trilogy_reader_get_uint16(&reader, &out_values[i].as.uint16));
|
1065
|
+
|
1066
|
+
break;
|
1067
|
+
case TRILOGY_TYPE_YEAR:
|
1068
|
+
CHECKED(trilogy_reader_get_uint16(&reader, &out_values[i].as.year));
|
1069
|
+
|
1070
|
+
break;
|
1071
|
+
case TRILOGY_TYPE_TINY:
|
1072
|
+
CHECKED(trilogy_reader_get_uint8(&reader, &out_values[i].as.uint8));
|
1073
|
+
|
1074
|
+
break;
|
1075
|
+
case TRILOGY_TYPE_DATE:
|
1076
|
+
case TRILOGY_TYPE_DATETIME:
|
1077
|
+
case TRILOGY_TYPE_TIMESTAMP: {
|
1078
|
+
uint8_t time_len;
|
1079
|
+
|
1080
|
+
CHECKED(trilogy_reader_get_uint8(&reader, &time_len));
|
1081
|
+
|
1082
|
+
out_values[i].as.date.year = 0;
|
1083
|
+
out_values[i].as.date.month = 0;
|
1084
|
+
out_values[i].as.date.day = 0;
|
1085
|
+
out_values[i].as.date.datetime.hour = 0;
|
1086
|
+
out_values[i].as.date.datetime.minute = 0;
|
1087
|
+
out_values[i].as.date.datetime.second = 0;
|
1088
|
+
out_values[i].as.date.datetime.micro_seconds = 0;
|
1089
|
+
|
1090
|
+
switch (time_len) {
|
1091
|
+
case 0:
|
1092
|
+
break;
|
1093
|
+
case 4:
|
1094
|
+
CHECKED(trilogy_reader_get_uint16(&reader, &out_values[i].as.date.year));
|
1095
|
+
CHECKED(trilogy_reader_get_uint8(&reader, &out_values[i].as.date.month));
|
1096
|
+
CHECKED(trilogy_reader_get_uint8(&reader, &out_values[i].as.date.day));
|
1097
|
+
|
1098
|
+
break;
|
1099
|
+
case 7:
|
1100
|
+
CHECKED(trilogy_reader_get_uint16(&reader, &out_values[i].as.date.year));
|
1101
|
+
CHECKED(trilogy_reader_get_uint8(&reader, &out_values[i].as.date.month));
|
1102
|
+
CHECKED(trilogy_reader_get_uint8(&reader, &out_values[i].as.date.day));
|
1103
|
+
CHECKED(trilogy_reader_get_uint8(&reader, &out_values[i].as.date.datetime.hour));
|
1104
|
+
CHECKED(trilogy_reader_get_uint8(&reader, &out_values[i].as.date.datetime.minute));
|
1105
|
+
CHECKED(trilogy_reader_get_uint8(&reader, &out_values[i].as.date.datetime.second));
|
1106
|
+
|
1107
|
+
break;
|
1108
|
+
case 11:
|
1109
|
+
CHECKED(trilogy_reader_get_uint16(&reader, &out_values[i].as.date.year));
|
1110
|
+
CHECKED(trilogy_reader_get_uint8(&reader, &out_values[i].as.date.month));
|
1111
|
+
CHECKED(trilogy_reader_get_uint8(&reader, &out_values[i].as.date.day));
|
1112
|
+
CHECKED(trilogy_reader_get_uint8(&reader, &out_values[i].as.date.datetime.hour));
|
1113
|
+
CHECKED(trilogy_reader_get_uint8(&reader, &out_values[i].as.date.datetime.minute));
|
1114
|
+
CHECKED(trilogy_reader_get_uint8(&reader, &out_values[i].as.date.datetime.second));
|
1115
|
+
CHECKED(trilogy_reader_get_uint32(&reader, &out_values[i].as.date.datetime.micro_seconds));
|
1116
|
+
|
1117
|
+
break;
|
1118
|
+
default:
|
1119
|
+
return TRILOGY_PROTOCOL_VIOLATION;
|
1120
|
+
}
|
1121
|
+
|
1122
|
+
break;
|
1123
|
+
}
|
1124
|
+
case TRILOGY_TYPE_TIME: {
|
1125
|
+
uint8_t time_len;
|
1126
|
+
|
1127
|
+
CHECKED(trilogy_reader_get_uint8(&reader, &time_len));
|
1128
|
+
|
1129
|
+
out_values[i].as.time.is_negative = false;
|
1130
|
+
out_values[i].as.time.days = 0;
|
1131
|
+
out_values[i].as.time.hour = 0;
|
1132
|
+
out_values[i].as.time.minute = 0;
|
1133
|
+
out_values[i].as.time.second = 0;
|
1134
|
+
out_values[i].as.time.micro_seconds = 0;
|
1135
|
+
|
1136
|
+
switch (time_len) {
|
1137
|
+
case 0:
|
1138
|
+
break;
|
1139
|
+
case 8: {
|
1140
|
+
uint8_t is_negative;
|
1141
|
+
|
1142
|
+
CHECKED(trilogy_reader_get_uint8(&reader, &is_negative));
|
1143
|
+
|
1144
|
+
out_values[i].as.time.is_negative = is_negative == 1;
|
1145
|
+
|
1146
|
+
CHECKED(trilogy_reader_get_uint32(&reader, &out_values[i].as.time.days));
|
1147
|
+
CHECKED(trilogy_reader_get_uint8(&reader, &out_values[i].as.time.hour));
|
1148
|
+
CHECKED(trilogy_reader_get_uint8(&reader, &out_values[i].as.time.minute));
|
1149
|
+
CHECKED(trilogy_reader_get_uint8(&reader, &out_values[i].as.time.second));
|
1150
|
+
|
1151
|
+
break;
|
1152
|
+
}
|
1153
|
+
case 12: {
|
1154
|
+
uint8_t is_negative;
|
1155
|
+
|
1156
|
+
CHECKED(trilogy_reader_get_uint8(&reader, &is_negative));
|
1157
|
+
|
1158
|
+
out_values[i].as.time.is_negative = is_negative == 1;
|
1159
|
+
|
1160
|
+
CHECKED(trilogy_reader_get_uint32(&reader, &out_values[i].as.time.days));
|
1161
|
+
CHECKED(trilogy_reader_get_uint8(&reader, &out_values[i].as.time.hour));
|
1162
|
+
CHECKED(trilogy_reader_get_uint8(&reader, &out_values[i].as.time.minute));
|
1163
|
+
CHECKED(trilogy_reader_get_uint8(&reader, &out_values[i].as.time.second));
|
1164
|
+
CHECKED(trilogy_reader_get_uint32(&reader, &out_values[i].as.time.micro_seconds));
|
1165
|
+
|
1166
|
+
break;
|
1167
|
+
}
|
1168
|
+
default:
|
1169
|
+
return TRILOGY_PROTOCOL_VIOLATION;
|
1170
|
+
}
|
1171
|
+
|
1172
|
+
break;
|
1173
|
+
}
|
1174
|
+
case TRILOGY_TYPE_NULL:
|
1175
|
+
default:
|
1176
|
+
// we cover TRILOGY_TYPE_NULL here because we should never hit this case
|
1177
|
+
// explicitly as it should be covered in the null bitmap
|
1178
|
+
return TRILOGY_UNKNOWN_TYPE;
|
1179
|
+
}
|
1180
|
+
}
|
1181
|
+
}
|
1182
|
+
|
1183
|
+
return trilogy_reader_finish(&reader);
|
1184
|
+
|
1185
|
+
fail:
|
1186
|
+
return rc;
|
1187
|
+
}
|
1188
|
+
|
686
1189
|
#undef CHECKED
|
@@ -95,6 +95,44 @@ int trilogy_reader_get_uint64(trilogy_reader_t *reader, uint64_t *out)
|
|
95
95
|
return TRILOGY_OK;
|
96
96
|
}
|
97
97
|
|
98
|
+
int trilogy_reader_get_float(trilogy_reader_t *reader, float *out)
|
99
|
+
{
|
100
|
+
CHECK(4);
|
101
|
+
|
102
|
+
union {
|
103
|
+
float f;
|
104
|
+
uint32_t u;
|
105
|
+
} float_val;
|
106
|
+
|
107
|
+
int rc = trilogy_reader_get_uint32(reader, &float_val.u);
|
108
|
+
if (rc != TRILOGY_OK) {
|
109
|
+
return rc;
|
110
|
+
}
|
111
|
+
|
112
|
+
*out = float_val.f;
|
113
|
+
|
114
|
+
return TRILOGY_OK;
|
115
|
+
}
|
116
|
+
|
117
|
+
int trilogy_reader_get_double(trilogy_reader_t *reader, double *out)
|
118
|
+
{
|
119
|
+
CHECK(8);
|
120
|
+
|
121
|
+
union {
|
122
|
+
double d;
|
123
|
+
uint64_t u;
|
124
|
+
} double_val;
|
125
|
+
|
126
|
+
int rc = trilogy_reader_get_uint64(reader, &double_val.u);
|
127
|
+
if (rc != TRILOGY_OK) {
|
128
|
+
return rc;
|
129
|
+
}
|
130
|
+
|
131
|
+
*out = double_val.d;
|
132
|
+
|
133
|
+
return TRILOGY_OK;
|
134
|
+
}
|
135
|
+
|
98
136
|
int trilogy_reader_get_lenenc(trilogy_reader_t *reader, uint64_t *out)
|
99
137
|
{
|
100
138
|
CHECK(1);
|