Skip to content

Commit ba7e010

Browse files
author
Ľudovít Lučenič
committed
Merge remote-tracking branch 'origin/some_additions_from_den' into gh-arinas
2 parents 7d1757e + c486eab commit ba7e010

File tree

8 files changed

+87
-73
lines changed

8 files changed

+87
-73
lines changed

src/dpq2/conv/bit.d

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
module dpq2.conv.bit;
22

33
import dpq2.conv.to_d_types;
4-
import dpq2.oids : OidType;
4+
import dpq2.oids: OidType;
55
import dpq2.value;
66

7-
import std.bitmanip : bigEndianToNative;
8-
import std.conv : to;
9-
import std.exception : enforce;
10-
import std.traits : hasMember;
7+
import std.bitmanip: bigEndianToNative;
8+
import std.conv: to;
9+
import std.traits: hasMember;
1110

1211

1312
template isBitString(T) {
@@ -21,16 +20,15 @@ struct BitString {
2120
immutable(ubyte)[] _data;
2221

2322
this(immutable(ubyte)[] binaryData) {
24-
enforce(binaryData.length >= uint.sizeof, "cannot construct bit string with insufficient data");
23+
enforceSize(binaryData, uint.sizeof, "cannot construct bit string with insufficient data");
2524

2625
this._data = binaryData;
2726

2827
this.stringLen = binaryData[0..uint.sizeof].bigEndianToNative!uint;
28+
assert(this.stringLen, "zero bit string length?");
2929

3030
binaryData = binaryData[uint.sizeof..$];
31-
3231
assert(binaryData.length >= this.byteLen, "data shorter than bit string length");
33-
assert(this.stringLen, "zero bit string length?");
3432

3533
this.bits = binaryData[0..this.byteLen].dup;
3634
}

src/dpq2/conv/native_tests.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import dpq2.conv.geometric: Line;
66
import dpq2.conv.ranges;
77
import std.bitmanip : BitArray;
88
import std.datetime;
9-
import std.string : replace;
9+
import std.string: replace;
1010
import std.typecons: Nullable;
1111
import std.uuid: UUID;
1212
import std.variant: Variant;

src/dpq2/conv/net.d

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
module dpq2.conv.net;
22

33
import dpq2.conv.to_d_types;
4-
import dpq2.oids : OidType;
4+
import dpq2.oids: OidType;
55
import dpq2.value;
66

7-
import std.bitmanip : bigEndianToNative;
8-
import std.conv : to;
9-
import std.exception : enforce;
10-
import std.format : format;
11-
import std.socket : AddressFamily;
12-
import std.traits : hasMember;
7+
import std.bitmanip: bigEndianToNative;
8+
import std.conv: to;
9+
import std.format: format;
10+
import std.socket: AddressFamily;
11+
import std.traits: hasMember;
1312

1413

1514
enum PG_TYPE : ushort {
@@ -31,20 +30,19 @@ struct NetworkAddress {
3130
immutable(ubyte)[] _data;
3231

3332
this(immutable(ubyte)[] binaryData) {
34-
enforce(binaryData.length >= uint.sizeof, "cannot construct network address with insufficient data");
33+
enforceSize(binaryData, uint.sizeof, "cannot construct network address with insufficient data");
3534

3635
this._data = binaryData;
3736

3837
this.family = binaryData[0].to!AddressFamily;
3938
this.netmask = binaryData[1];
4039
this.type = binaryData[2].to!PG_TYPE;
4140
this.addressLen = binaryData[3];
41+
assert(this.addressLen, "zero address length?");
42+
assert(this.addressLen <= binaryData.length, "data shorter than address length");
4243

4344
binaryData = binaryData[4..$];
4445

45-
assert(this.addressLen <= binaryData.length, "data shorter than address length");
46-
assert(this.addressLen, "zero address length?");
47-
4846
this.address = binaryData[0..this.addressLen].dup;
4947
}
5048

src/dpq2/conv/ranges.d

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,27 @@
11
module dpq2.conv.ranges;
22

33

4-
import dpq2.conv.time : TimeStamp, TimeStampUTC;
4+
import dpq2.conv.time: TimeStamp, TimeStampUTC;
55
import dpq2.conv.to_d_types;
6-
import dpq2.oids : OidType;
6+
import dpq2.oids: OidType;
77
import dpq2.value;
88

9-
import std.bitmanip : bigEndianToNative;
10-
import std.conv : to;
11-
import std.datetime.date : Date;
12-
import std.exception : enforce;
13-
import std.traits : TemplateOf;
9+
import std.bitmanip: bigEndianToNative;
10+
import std.conv: to;
11+
import std.datetime.date: Date;
12+
import std.traits: TemplateOf;
1413

1514

1615
enum PG_RANGE : ubyte {
1716
/* A range's flags byte contains these bits: */
18-
EMPTY = 0x01, /* range is empty */
19-
LB_INC = 0x02, /* lower bound is inclusive */
20-
UB_INC = 0x04, /* upper bound is inclusive */
21-
LB_INF = 0x08, /* lower bound is -infinity */
22-
UB_INF = 0x10, /* upper bound is +infinity */
23-
LB_NULL = 0x20, /* lower bound is null (NOT USED) */
24-
UB_NULL = 0x40, /* upper bound is null (NOT USED) */
25-
CONTAIN_EMPTY = 0x80 /* marks a GiST internal-page entry whose
17+
EMPTY = 0x01, /** range is empty */
18+
LB_INC = 0x02, /** lower bound is inclusive */
19+
UB_INC = 0x04, /** upper bound is inclusive */
20+
LB_INF = 0x08, /** lower bound is -infinity */
21+
UB_INF = 0x10, /** upper bound is +infinity */
22+
LB_NULL = 0x20, /** lower bound is null (NOT USED) */
23+
UB_NULL = 0x40, /** upper bound is null (NOT USED) */
24+
CONTAIN_EMPTY = 0x80 /** marks a GiST internal-page entry whose
2625
* subtree contains some empty ranges */
2726
}
2827

@@ -49,7 +48,7 @@ if (isRangeType!(T,O))
4948
immutable(ubyte)[] _data;
5049

5150
this(immutable(ubyte)[] binaryData) {
52-
enforce(binaryData.length >= 1, "cannot construct range with insufficient data");
51+
enforceSize(binaryData, 1, "cannot construct range with insufficient data");
5352

5453
this._data = binaryData;
5554

@@ -107,7 +106,7 @@ if (__traits(isSame, TemplateOf!R, Range))
107106
immutable(ubyte)[] _data;
108107

109108
this(immutable(ubyte)[] binaryData) {
110-
enforce(binaryData.length >= uint.sizeof, "cannot construct multirange with insufficient data");
109+
enforceSize(binaryData, uint.sizeof, "cannot construct multirange with insufficient data");
111110

112111
this._data = binaryData;
113112
binaryData = binaryData[uint.sizeof..$];
@@ -123,7 +122,12 @@ if (__traits(isSame, TemplateOf!R, Range))
123122
size_t length() @property { return _data.length ? _data[0..uint.sizeof].bigEndianToNative!uint : 0; }
124123

125124
R opIndex(size_t idx) {
126-
enforce(idx < this.length, "multirange index out of bounds: " ~ this.length.to!string ~ "/" ~ idx.to!string);
125+
if(!(idx < this.length))
126+
throw new ValueConvException(
127+
ConvExceptionType.OUT_OF_RANGE,
128+
"multirange index out of bounds: " ~ this.length.to!string ~ "/" ~ idx.to!string,
129+
);
130+
127131
return data[idx];
128132
}
129133

@@ -146,19 +150,19 @@ if (__traits(isSame, TemplateOf!R, Range))
146150
}
147151
}
148152

149-
alias Range!(int, OidType.Int4) Int4Range;
150-
alias Range!(long, OidType.Int8) Int8Range;
151-
alias Range!(string, OidType.Numeric, 0) NumRange;
152-
alias Range!(TimeStamp, OidType.TimeStamp, 8) TsRange;
153-
alias Range!(TimeStampUTC, OidType.TimeStampWithZone, 8) TsTzRange;
154-
alias Range!(Date, OidType.Date) DateRange;
155-
156-
alias MultiRange!Int4Range Int4MultiRange;
157-
alias MultiRange!Int8Range Int8MultiRange;
158-
alias MultiRange!NumRange NumMultiRange;
159-
alias MultiRange!TsRange TsMultiRange;
160-
alias MultiRange!TsTzRange TsTzMultiRange;
161-
alias MultiRange!DateRange DateMultiRange;
153+
alias Int4Range = Range!(int, OidType.Int4);
154+
alias Int8Range = Range!(long, OidType.Int8);
155+
alias NumRange = Range!(string, OidType.Numeric, 0);
156+
alias TsRange = Range!(TimeStamp, OidType.TimeStamp, 8);
157+
alias TsTzRange = Range!(TimeStampUTC, OidType.TimeStampWithZone, 8);
158+
alias DateRange = Range!(Date, OidType.Date);
159+
160+
alias Int4MultiRange = MultiRange!Int4Range;
161+
alias Int8MultiRange = MultiRange!Int8Range;
162+
alias NumMultiRange = MultiRange!NumRange;
163+
alias TsMultiRange = MultiRange!TsRange;
164+
alias TsTzMultiRange = MultiRange!TsTzRange;
165+
alias DateMultiRange = MultiRange!DateRange;
162166

163167
package:
164168

src/dpq2/conv/to_d_types.d

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ import dpq2.conv.from_d_types;
1212
import dpq2.conv.numeric: rawValueToNumeric;
1313
import dpq2.conv.time: binaryValueAs, TimeStamp, TimeStampUTC, TimeOfDayWithTZ, Interval;
1414
import dpq2.conv.geometric: binaryValueAs, Line;
15-
import dpq2.conv.net : binaryValueAs;
16-
import dpq2.conv.bit : binaryValueAs;
17-
import dpq2.conv.ranges : binaryValueAs;
18-
import dpq2.conv.tsearch : binaryValueAs;
19-
import dpq2.conv.arrays : binaryValueAs;
15+
import dpq2.conv.net: binaryValueAs;
16+
import dpq2.conv.bit: binaryValueAs;
17+
import dpq2.conv.ranges: binaryValueAs;
18+
import dpq2.conv.tsearch: binaryValueAs;
19+
import dpq2.conv.arrays: binaryValueAs;
2020

2121
import vibe.data.json: Json, parseJsonString;
2222
import vibe.data.bson: Bson;

src/dpq2/conv/to_variant.d

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ Variant toVariant(bool isNullablePayload = true)(in Value v) @safe
100100

101101
case Int4RangeArray: return retArray__!(dpq2.conv.ranges.Int4Range);
102102
case Int8RangeArray: return retArray__!(dpq2.conv.ranges.Int8Range);
103-
case NumRangeArray: return retArray__!(dpq2.conv.ranges.NumRange);
103+
case NumRangeArray: return retArray__!(dpq2.conv.ranges.NumRange);
104104
case DateRangeArray: return retArray__!(dpq2.conv.ranges.DateRange);
105105
case TimeStampRangeArray: return retArray__!(dpq2.conv.ranges.TsRange);
106106
case TimeStampWithZoneRangeArray: return retArray__!(dpq2.conv.ranges.TsTzRange);
@@ -116,7 +116,7 @@ Variant toVariant(bool isNullablePayload = true)(in Value v) @safe
116116
case Int8MultiRangeArray: return retArray__!(dpq2.conv.ranges.Int8MultiRange);
117117
case NumMultiRangeArray: return retArray__!(dpq2.conv.ranges.NumMultiRange);
118118
case DateMultiRangeArray: return retArray__!(dpq2.conv.ranges.DateMultiRange);
119-
case TimeStampMultiRangeArray: return retArray__!(dpq2.conv.ranges.TsMultiRange);
119+
case TimeStampMultiRangeArray: return retArray__!(dpq2.conv.ranges.TsMultiRange);
120120
case TimeStampWithZoneMultiRangeArray: return retArray__!(dpq2.conv.ranges.TsTzMultiRange);
121121

122122
case ByteArray: return retVariant!PGbytea;

src/dpq2/conv/tsearch.d

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
module dpq2.conv.tsearch;
22

33
import dpq2.conv.to_d_types;
4-
import dpq2.oids : OidType;
4+
import dpq2.oids: OidType;
55
import dpq2.value;
66

7-
import std.bitmanip : bigEndianToNative;
8-
import std.conv : to;
9-
import std.exception : enforce;
10-
import std.stdio : writefln;
11-
import std.string : fromStringz;
12-
import std.traits : hasMember;
7+
import std.bitmanip: bigEndianToNative;
8+
import std.conv: to;
9+
import std.stdio: writefln;
10+
import std.string: fromStringz;
11+
import std.traits: hasMember;
1312

1413

1514
template isTsQuery(T) {
@@ -64,16 +63,15 @@ struct TsQuery {
6463
immutable(ubyte)[] _data;
6564

6665
this(immutable(ubyte)[] binaryData) {
67-
enforce(binaryData.length >= uint.sizeof, "cannot construct text search query with insufficient data");
66+
enforceSize(binaryData, uint.sizeof, "cannot construct text search query with insufficient data");
6867

6968
this._data = binaryData;
7069

7170
auto count = binaryData[0..uint.sizeof].bigEndianToNative!uint;
71+
assert(count, "zero token count?");
7272

7373
binaryData = binaryData[uint.sizeof..$];
7474

75-
assert(count, "zero token count?");
76-
7775
for (uint i = 0; i < count; i++) {
7876
TsToken token;
7977

@@ -109,7 +107,12 @@ struct TsQuery {
109107
size_t length() @property { return tokens.length; }
110108

111109
auto opIndex(size_t idx) {
112-
enforce(idx < this.tokens.length, "tokens index out of bounds: " ~ this.tokens.length.to!string ~ "/" ~ idx.to!string);
110+
if(!(idx < this.tokens.length))
111+
throw new ValueConvException(
112+
ConvExceptionType.OUT_OF_RANGE,
113+
"tokens index out of bounds: " ~ this.tokens.length.to!string ~ "/" ~ idx.to!string,
114+
);
115+
113116
return tokens[idx];
114117
}
115118

@@ -140,16 +143,15 @@ struct TsVector {
140143
immutable(ubyte)[] _data;
141144

142145
this(immutable(ubyte)[] binaryData) {
143-
enforce(binaryData.length >= uint.sizeof, "cannot construct text search vector with insufficient data");
146+
enforceSize(binaryData, uint.sizeof, "cannot construct text search vector with insufficient data");
144147

145148
this._data = binaryData;
146149

147150
auto count = binaryData[0..uint.sizeof].bigEndianToNative!uint;
151+
assert(count, "zero lexeme count?");
148152

149153
binaryData = binaryData[uint.sizeof..$];
150154

151-
assert(count, "zero lexeme count?");
152-
153155
for (uint i = 0; i < count; i++) {
154156
TsLexeme lexeme;
155157

@@ -170,7 +172,12 @@ struct TsVector {
170172
size_t length() @property { return lexemes.length; }
171173

172174
auto opIndex(size_t idx) {
173-
enforce(idx < this.lexemes.length, "lexemes index out of bounds: " ~ this.lexemes.length.to!string ~ "/" ~ idx.to!string);
175+
if(!(idx < this.lexemes.length))
176+
throw new ValueConvException(
177+
ConvExceptionType.OUT_OF_RANGE,
178+
"lexemes index out of bounds: " ~ this.lexemes.length.to!string ~ "/" ~ idx.to!string,
179+
);
180+
174181
return lexemes[idx];
175182
}
176183

src/dpq2/value.d

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,3 +167,10 @@ package void throwTypeComplaint(OidType receivedType, in string expectedType, st
167167
file, line
168168
);
169169
}
170+
171+
//TODO: use for all ConvExceptionType.SIZE_MISMATCH checks
172+
package void enforceSize(T)(const ref T binaryData, size_t sz, string msg, string file = __FILE__, size_t line = __LINE__)
173+
{
174+
if(!(binaryData.length >= sz))
175+
throw new ValueConvException(ConvExceptionType.SIZE_MISMATCH, msg, file, line);
176+
}

0 commit comments

Comments
 (0)