Skip to content

Commit 155484b

Browse files
committed
fields_base erases fields by name when id is field::unknown
1 parent 8d75f0a commit 155484b

5 files changed

Lines changed: 88 additions & 139 deletions

File tree

include/boost/http_proto/fields_base.hpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -926,7 +926,7 @@ class fields_base
926926
detail::header const&);
927927

928928
void
929-
insert_impl_unchecked(
929+
insert_unchecked_impl(
930930
field id,
931931
core::string_view name,
932932
core::string_view value,
@@ -948,14 +948,20 @@ class fields_base
948948
std::size_t i,
949949
field id) noexcept;
950950

951-
void raw_erase(
951+
void
952+
raw_erase(
952953
std::size_t) noexcept;
953954

954955
std::size_t
955956
erase_all_impl(
956957
std::size_t i0,
957958
field id) noexcept;
958959

960+
std::size_t
961+
erase_all_impl(
962+
std::size_t i0,
963+
core::string_view name) noexcept;
964+
959965
std::size_t
960966
offset(
961967
std::size_t i) const noexcept;

src/fields_base.cpp

Lines changed: 64 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -150,11 +150,6 @@ class fields_base::
150150
std::size_t extra_char,
151151
std::size_t extra_field);
152152

153-
void
154-
copy_prefix(
155-
std::size_t n,
156-
std::size_t i) noexcept;
157-
158153
void
159154
move_chars(
160155
char* dest,
@@ -204,27 +199,6 @@ grow(
204199
self_.h_.count + extra_field));
205200
}
206201

207-
void
208-
fields_base::
209-
op_t::
210-
copy_prefix(
211-
std::size_t n,
212-
std::size_t i) noexcept
213-
{
214-
// copy first n chars
215-
std::memcpy(
216-
self_.h_.buf,
217-
cbuf_,
218-
n);
219-
// copy first i entries
220-
if(i > 0)
221-
std::memcpy(
222-
self_.h_.tab_() - i,
223-
reinterpret_cast<entry*>(
224-
buf_ + cap_) - i,
225-
i * sizeof(entry));
226-
}
227-
228202
void
229203
fields_base::
230204
op_t::
@@ -597,105 +571,25 @@ erase(
597571
if(id == field::unknown)
598572
detail::throw_logic_error();
599573

600-
#if 1
601-
auto const end_ = end();
602-
auto it = find_last(end_, id);
603-
if(it == end_)
574+
auto const i0 = h_.find(id);
575+
if(i0 == h_.count)
604576
return 0;
605-
std::size_t n = 1;
606-
auto const begin_ = begin();
607-
raw_erase(it.i_);
608-
while(it != begin_)
609-
{
610-
--it;
611-
if(it->id == id)
612-
{
613-
raw_erase(it.i_);
614-
++n;
615-
}
616-
}
617-
h_.on_erase_all(id);
618-
return n;
619-
#else
620-
std::size_t n = 0;
621-
auto it0 = find(id);
622-
auto const end_ = end();
623-
if(it0 != end_)
624-
{
625-
auto it1 = it0;
626-
std::size_t total = 0;
627-
std::size_t size = 0;
628-
// [it0, it1) run of id
629-
for(;;)
630-
{
631-
size += length(it1.i_);
632-
++it1;
633-
if(it1 == end_)
634-
goto finish;
635-
if(it1->id != id)
636-
break;
637-
}
638-
std::memmove(
639-
h_.buf + offset(it0.i_),
640-
h_.buf + offset(it1.i_),
641-
h_.size - offset(it2.i_));
642-
643-
finish:
644-
h_.size -= size;
645-
h_.count -= n;
646-
}
647-
return n;
648-
#endif
577+
return erase_all_impl(i0, id);
649578
}
650579

651580
std::size_t
652581
fields_base::
653582
erase(
654583
core::string_view name) noexcept
655584
{
656-
auto it0 = find(name);
657-
auto const end_ = end();
658-
if(it0 == end_)
585+
auto const i0 = h_.find(name);
586+
if(i0 == h_.count)
659587
return 0;
660-
auto it = end_;
661-
std::size_t n = 1;
662-
auto const id = it0->id;
588+
auto const ft = h_.tab();
589+
auto const id = ft[i0].id;
663590
if(id == field::unknown)
664-
{
665-
// fix self-intersection
666-
name = it0->name;
667-
668-
for(;;)
669-
{
670-
--it;
671-
if(it == it0)
672-
break;
673-
if(grammar::ci_is_equal(
674-
it->name, name))
675-
{
676-
raw_erase(it.i_);
677-
++n;
678-
}
679-
}
680-
raw_erase(it.i_);
681-
}
682-
else
683-
{
684-
for(;;)
685-
{
686-
--it;
687-
if(it == it0)
688-
break;
689-
if(it->id == id)
690-
{
691-
raw_erase(it.i_);
692-
++n;
693-
}
694-
}
695-
raw_erase(it.i_);
696-
h_.on_erase_all(id);
697-
}
698-
return n;
591+
return erase_all_impl(i0, name);
592+
return erase_all_impl(i0, id);
699593
}
700594

701595
//------------------------------------------------
@@ -843,9 +737,6 @@ set(
843737
return;
844738
}
845739

846-
value = rv->value;
847-
bool has_obs_fold = rv->has_obs_fold;
848-
849740
auto const i0 = h_.find(id);
850741
if(i0 != h_.count)
851742
{
@@ -857,15 +748,19 @@ set(
857748
h_.size - length(i0);
858749
auto const n =
859750
ft[i0].nn + 2 +
860-
value.size() + 2;
751+
rv->value.size() + 2;
861752
// VFALCO missing overflow check
862753
reserve_bytes(n0 + n);
863754
}
864755
erase_all_impl(i0, id);
865756
}
866757

867-
insert_impl_unchecked(
868-
id, to_string(id), value, h_.count, has_obs_fold);
758+
insert_unchecked_impl(
759+
id,
760+
to_string(id),
761+
rv->value,
762+
h_.count,
763+
rv->has_obs_fold);
869764
}
870765

871766
// erase existing fields with name
@@ -888,9 +783,6 @@ set(
888783
return;
889784
}
890785

891-
value = rv->value;
892-
bool has_obs_fold = rv->has_obs_fold;
893-
894786
auto const i0 = h_.find(name);
895787
if(i0 != h_.count)
896788
{
@@ -903,17 +795,23 @@ set(
903795
h_.size - length(i0);
904796
auto const n =
905797
ft[i0].nn + 2 +
906-
value.size() + 2;
798+
rv->value.size() + 2;
907799
// VFALCO missing overflow check
908800
reserve_bytes(n0 + n);
909801
}
910802
// VFALCO simple algorithm but
911803
// costs one extra memmove
912-
erase_all_impl(i0, id);
804+
if(id != field::unknown)
805+
erase_all_impl(i0, id);
806+
else
807+
erase_all_impl(i0, name);
913808
}
914-
insert_impl_unchecked(
809+
insert_unchecked_impl(
915810
string_to_field(name),
916-
name, value, h_.count, has_obs_fold);
811+
name,
812+
rv->value,
813+
h_.count,
814+
rv->has_obs_fold);
917815
}
918816

919817
//------------------------------------------------
@@ -966,7 +864,7 @@ copy_impl(
966864

967865
void
968866
fields_base::
969-
insert_impl_unchecked(
867+
insert_unchecked_impl(
970868
field id,
971869
core::string_view name,
972870
core::string_view value,
@@ -1086,8 +984,12 @@ insert_impl(
1086984
return;
1087985
}
1088986

1089-
insert_impl_unchecked(
1090-
id, name, rv->value, before, rv->has_obs_fold);
987+
insert_unchecked_impl(
988+
id,
989+
name,
990+
rv->value,
991+
before,
992+
rv->has_obs_fold);
1091993
}
1092994

1093995
// erase i and update metadata
@@ -1098,8 +1000,7 @@ erase_impl(
10981000
field id) noexcept
10991001
{
11001002
raw_erase(i);
1101-
if(id != field::unknown)
1102-
h_.on_erase(id);
1003+
h_.on_erase(id);
11031004
}
11041005

11051006
//------------------------------------------------
@@ -1157,6 +1058,35 @@ erase_all_impl(
11571058
return n;
11581059
}
11591060

1061+
// erase all fields with name
1062+
// when id == field::unknown
1063+
std::size_t
1064+
fields_base::
1065+
erase_all_impl(
1066+
std::size_t i0,
1067+
core::string_view name) noexcept
1068+
{
1069+
std::size_t n = 1;
1070+
std::size_t i = h_.count - 1;
1071+
auto const ft = h_.tab();
1072+
auto const* p = h_.cbuf + h_.prefix;
1073+
while(i > i0)
1074+
{
1075+
core::string_view s(
1076+
p + ft[i].np, ft[i].nn);
1077+
if(s == name)
1078+
{
1079+
raw_erase(i);
1080+
++n;
1081+
}
1082+
// go backwards to
1083+
// reduce memmoves
1084+
--i;
1085+
}
1086+
raw_erase(i0);
1087+
return n;
1088+
}
1089+
11601090
// return i-th field absolute offset
11611091
std::size_t
11621092
fields_base::
@@ -1166,10 +1096,8 @@ offset(
11661096
if(i == 0)
11671097
return h_.prefix;
11681098
if(i < h_.count)
1169-
return h_.prefix +
1170-
h_.tab_()[0-(static_cast<std::ptrdiff_t>(i) + 1)].np;
1099+
return h_.prefix + h_.tab()[i].np;
11711100
// make final CRLF the last "field"
1172-
//BOOST_ASSERT(i == h_.count);
11731101
return h_.size - 2;
11741102
}
11751103

src/rfc/transfer_coding_rule.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ struct transfer_coding_rule_t
7575
} extension;
7676
};
7777

78+
BOOST_HTTP_PROTO_DECL
7879
auto
7980
parse(
8081
char const*& it,

test/unit/Jamfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ local SOURCES =
7070
rfc/quoted_token_rule.cpp
7171
rfc/quoted_token_view.cpp
7272
rfc/token_rule.cpp
73-
rfc/transfer_encoding_rule.cpp
73+
rfc/transfer_coding_rule.cpp
7474
rfc/detail/rules.cpp
7575
;
7676

test/unit/fields_base.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,6 +1133,20 @@ struct fields_base_test
11331133
"Server: y\r\n"
11341134
"\r\n");
11351135

1136+
check(
1137+
"UnkownId0: w\r\n"
1138+
"UnkownId1: x\r\n"
1139+
"UnkownId2: y\r\n"
1140+
"\r\n",
1141+
[](fields_base& f)
1142+
{
1143+
f.set("UnkownId1", "z");
1144+
},
1145+
"UnkownId0: w\r\n"
1146+
"UnkownId2: y\r\n"
1147+
"UnkownId1: z\r\n"
1148+
"\r\n");
1149+
11361150
check(
11371151
"T: 1\r\n"
11381152
"Server: xx\r\n"

0 commit comments

Comments
 (0)