@@ -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-
228202void
229203fields_base::
230204op_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
651580std::size_t
652581fields_base::
653582erase (
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// ------------------------------------------------
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
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
967865void
968866fields_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
11611091std::size_t
11621092fields_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
0 commit comments