@@ -729,21 +729,24 @@ pub mod writer {
729
729
use std:: num:: Int ;
730
730
use std:: old_io:: { Writer , Seek } ;
731
731
use std:: old_io;
732
+ use std:: slice:: bytes;
732
733
733
734
use super :: { EsVec , EsMap , EsEnum , EsSub8 , EsSub32 , EsVecElt , EsMapKey ,
734
735
EsU64 , EsU32 , EsU16 , EsU8 , EsInt , EsI64 , EsI32 , EsI16 , EsI8 ,
735
736
EsBool , EsF64 , EsF32 , EsChar , EsStr , EsMapVal , EsUint ,
736
737
EsOpaque , NUM_IMPLICIT_TAGS , NUM_TAGS } ;
738
+ use super :: io:: SeekableMemWriter ;
737
739
738
740
use serialize;
739
741
740
742
741
743
pub type EncodeResult = old_io:: IoResult < ( ) > ;
742
744
743
745
// rbml writing
744
- pub struct Encoder < ' a , W : ' a > {
745
- pub writer : & ' a mut W ,
746
+ pub struct Encoder < ' a > {
747
+ pub writer : & ' a mut SeekableMemWriter ,
746
748
size_positions : Vec < uint > ,
749
+ relax_limit : u64 , // do not move encoded bytes before this position
747
750
}
748
751
749
752
fn write_tag < W : Writer > ( w : & mut W , n : uint ) -> EncodeResult {
@@ -788,19 +791,21 @@ pub mod writer {
788
791
} )
789
792
}
790
793
791
- impl < ' a , W : Writer + Seek > Encoder < ' a , W > {
792
- pub fn new ( w : & ' a mut W ) -> Encoder < ' a , W > {
794
+ impl < ' a > Encoder < ' a > {
795
+ pub fn new ( w : & ' a mut SeekableMemWriter ) -> Encoder < ' a > {
793
796
Encoder {
794
797
writer : w,
795
798
size_positions : vec ! ( ) ,
799
+ relax_limit : 0 ,
796
800
}
797
801
}
798
802
799
803
/// FIXME(pcwalton): Workaround for badness in trans. DO NOT USE ME.
800
- pub unsafe fn unsafe_clone ( & self ) -> Encoder < ' a , W > {
804
+ pub unsafe fn unsafe_clone ( & self ) -> Encoder < ' a > {
801
805
Encoder {
802
806
writer : mem:: transmute_copy ( & self . writer ) ,
803
807
size_positions : self . size_positions . clone ( ) ,
808
+ relax_limit : self . relax_limit ,
804
809
}
805
810
}
806
811
@@ -822,11 +827,29 @@ pub mod writer {
822
827
let cur_pos = try!( self . writer . tell ( ) ) ;
823
828
try!( self . writer . seek ( last_size_pos as i64 , old_io:: SeekSet ) ) ;
824
829
let size = cur_pos as uint - last_size_pos - 4 ;
825
- try!( write_sized_vuint ( self . writer , size, 4 ) ) ;
826
- let r = try!( self . writer . seek ( cur_pos as i64 , old_io:: SeekSet ) ) ;
830
+
831
+ // relax the size encoding for small tags (bigger tags are costly to move).
832
+ // we should never try to move the stable positions, however.
833
+ const RELAX_MAX_SIZE : uint = 0x100 ;
834
+ if size <= RELAX_MAX_SIZE && last_size_pos >= self . relax_limit as uint {
835
+ // we can't alter the buffer in place, so have a temporary buffer
836
+ let mut buf = [ 0u8 ; RELAX_MAX_SIZE ] ;
837
+ {
838
+ let data = & self . writer . get_ref ( ) [ last_size_pos+4 ..cur_pos as uint ] ;
839
+ bytes:: copy_memory ( & mut buf, data) ;
840
+ }
841
+
842
+ // overwrite the size and data and continue
843
+ try!( write_vuint ( self . writer , size) ) ;
844
+ try!( self . writer . write_all ( & buf[ ..size] ) ) ;
845
+ } else {
846
+ // overwrite the size with an overlong encoding and skip past the data
847
+ try!( write_sized_vuint ( self . writer , size, 4 ) ) ;
848
+ try!( self . writer . seek ( cur_pos as i64 , old_io:: SeekSet ) ) ;
849
+ }
827
850
828
851
debug ! ( "End tag (size = {:?})" , size) ;
829
- Ok ( r )
852
+ Ok ( ( ) )
830
853
}
831
854
832
855
pub fn wr_tag < F > ( & mut self , tag_id : uint , blk : F ) -> EncodeResult where
@@ -933,12 +956,19 @@ pub mod writer {
933
956
debug ! ( "Write str: {:?}" , s) ;
934
957
self . writer . write_all ( s. as_bytes ( ) )
935
958
}
936
- }
937
959
938
- // FIXME (#2743): optionally perform "relaxations" on end_tag to more
939
- // efficiently encode sizes; this is a fixed point iteration
960
+ /// Returns the current position while marking it stable, i.e.
961
+ /// generated bytes so far woundn't be affected by relaxation.
962
+ pub fn mark_stable_position ( & mut self ) -> u64 {
963
+ let pos = self . writer . tell ( ) . unwrap ( ) ;
964
+ if self . relax_limit < pos {
965
+ self . relax_limit = pos;
966
+ }
967
+ pos
968
+ }
969
+ }
940
970
941
- impl < ' a , W : Writer + Seek > Encoder < ' a , W > {
971
+ impl < ' a > Encoder < ' a > {
942
972
// used internally to emit things like the vector length and so on
943
973
fn _emit_tagged_sub ( & mut self , v : uint ) -> EncodeResult {
944
974
if let Some ( v) = v. to_u8 ( ) {
@@ -955,15 +985,15 @@ pub mod writer {
955
985
}
956
986
957
987
pub fn emit_opaque < F > ( & mut self , f : F ) -> EncodeResult where
958
- F : FnOnce ( & mut Encoder < W > ) -> EncodeResult ,
988
+ F : FnOnce ( & mut Encoder ) -> EncodeResult ,
959
989
{
960
990
try!( self . start_tag ( EsOpaque as uint ) ) ;
961
991
try!( f ( self ) ) ;
962
992
self . end_tag ( )
963
993
}
964
994
}
965
995
966
- impl < ' a , W : Writer + Seek > serialize:: Encoder for Encoder < ' a , W > {
996
+ impl < ' a > serialize:: Encoder for Encoder < ' a > {
967
997
type Error = old_io:: IoError ;
968
998
969
999
fn emit_nil ( & mut self ) -> EncodeResult {
@@ -1023,7 +1053,7 @@ pub mod writer {
1023
1053
}
1024
1054
1025
1055
fn emit_enum < F > ( & mut self , _name : & str , f : F ) -> EncodeResult where
1026
- F : FnOnce ( & mut Encoder < ' a , W > ) -> EncodeResult ,
1056
+ F : FnOnce ( & mut Encoder < ' a > ) -> EncodeResult ,
1027
1057
{
1028
1058
try!( self . start_tag ( EsEnum as uint ) ) ;
1029
1059
try!( f ( self ) ) ;
@@ -1035,14 +1065,14 @@ pub mod writer {
1035
1065
v_id : uint ,
1036
1066
_: uint ,
1037
1067
f : F ) -> EncodeResult where
1038
- F : FnOnce ( & mut Encoder < ' a , W > ) -> EncodeResult ,
1068
+ F : FnOnce ( & mut Encoder < ' a > ) -> EncodeResult ,
1039
1069
{
1040
1070
try!( self . _emit_tagged_sub ( v_id) ) ;
1041
1071
f ( self )
1042
1072
}
1043
1073
1044
1074
fn emit_enum_variant_arg < F > ( & mut self , _: uint , f : F ) -> EncodeResult where
1045
- F : FnOnce ( & mut Encoder < ' a , W > ) -> EncodeResult ,
1075
+ F : FnOnce ( & mut Encoder < ' a > ) -> EncodeResult ,
1046
1076
{
1047
1077
f ( self )
1048
1078
}
@@ -1052,7 +1082,7 @@ pub mod writer {
1052
1082
v_id : uint ,
1053
1083
cnt : uint ,
1054
1084
f : F ) -> EncodeResult where
1055
- F : FnOnce ( & mut Encoder < ' a , W > ) -> EncodeResult ,
1085
+ F : FnOnce ( & mut Encoder < ' a > ) -> EncodeResult ,
1056
1086
{
1057
1087
self . emit_enum_variant ( v_name, v_id, cnt, f)
1058
1088
}
@@ -1061,62 +1091,62 @@ pub mod writer {
1061
1091
_: & str ,
1062
1092
idx : uint ,
1063
1093
f : F ) -> EncodeResult where
1064
- F : FnOnce ( & mut Encoder < ' a , W > ) -> EncodeResult ,
1094
+ F : FnOnce ( & mut Encoder < ' a > ) -> EncodeResult ,
1065
1095
{
1066
1096
self . emit_enum_variant_arg ( idx, f)
1067
1097
}
1068
1098
1069
1099
fn emit_struct < F > ( & mut self , _: & str , _len : uint , f : F ) -> EncodeResult where
1070
- F : FnOnce ( & mut Encoder < ' a , W > ) -> EncodeResult ,
1100
+ F : FnOnce ( & mut Encoder < ' a > ) -> EncodeResult ,
1071
1101
{
1072
1102
f ( self )
1073
1103
}
1074
1104
1075
1105
fn emit_struct_field < F > ( & mut self , _name : & str , _: uint , f : F ) -> EncodeResult where
1076
- F : FnOnce ( & mut Encoder < ' a , W > ) -> EncodeResult ,
1106
+ F : FnOnce ( & mut Encoder < ' a > ) -> EncodeResult ,
1077
1107
{
1078
1108
f ( self )
1079
1109
}
1080
1110
1081
1111
fn emit_tuple < F > ( & mut self , len : uint , f : F ) -> EncodeResult where
1082
- F : FnOnce ( & mut Encoder < ' a , W > ) -> EncodeResult ,
1112
+ F : FnOnce ( & mut Encoder < ' a > ) -> EncodeResult ,
1083
1113
{
1084
1114
self . emit_seq ( len, f)
1085
1115
}
1086
1116
fn emit_tuple_arg < F > ( & mut self , idx : uint , f : F ) -> EncodeResult where
1087
- F : FnOnce ( & mut Encoder < ' a , W > ) -> EncodeResult ,
1117
+ F : FnOnce ( & mut Encoder < ' a > ) -> EncodeResult ,
1088
1118
{
1089
1119
self . emit_seq_elt ( idx, f)
1090
1120
}
1091
1121
1092
1122
fn emit_tuple_struct < F > ( & mut self , _: & str , len : uint , f : F ) -> EncodeResult where
1093
- F : FnOnce ( & mut Encoder < ' a , W > ) -> EncodeResult ,
1123
+ F : FnOnce ( & mut Encoder < ' a > ) -> EncodeResult ,
1094
1124
{
1095
1125
self . emit_seq ( len, f)
1096
1126
}
1097
1127
fn emit_tuple_struct_arg < F > ( & mut self , idx : uint , f : F ) -> EncodeResult where
1098
- F : FnOnce ( & mut Encoder < ' a , W > ) -> EncodeResult ,
1128
+ F : FnOnce ( & mut Encoder < ' a > ) -> EncodeResult ,
1099
1129
{
1100
1130
self . emit_seq_elt ( idx, f)
1101
1131
}
1102
1132
1103
1133
fn emit_option < F > ( & mut self , f : F ) -> EncodeResult where
1104
- F : FnOnce ( & mut Encoder < ' a , W > ) -> EncodeResult ,
1134
+ F : FnOnce ( & mut Encoder < ' a > ) -> EncodeResult ,
1105
1135
{
1106
1136
self . emit_enum ( "Option" , f)
1107
1137
}
1108
1138
fn emit_option_none ( & mut self ) -> EncodeResult {
1109
1139
self . emit_enum_variant ( "None" , 0 , 0 , |_| Ok ( ( ) ) )
1110
1140
}
1111
1141
fn emit_option_some < F > ( & mut self , f : F ) -> EncodeResult where
1112
- F : FnOnce ( & mut Encoder < ' a , W > ) -> EncodeResult ,
1142
+ F : FnOnce ( & mut Encoder < ' a > ) -> EncodeResult ,
1113
1143
{
1114
1144
1115
1145
self . emit_enum_variant ( "Some" , 1 , 1 , f)
1116
1146
}
1117
1147
1118
1148
fn emit_seq < F > ( & mut self , len : uint , f : F ) -> EncodeResult where
1119
- F : FnOnce ( & mut Encoder < ' a , W > ) -> EncodeResult ,
1149
+ F : FnOnce ( & mut Encoder < ' a > ) -> EncodeResult ,
1120
1150
{
1121
1151
1122
1152
try!( self . start_tag ( EsVec as uint ) ) ;
@@ -1126,7 +1156,7 @@ pub mod writer {
1126
1156
}
1127
1157
1128
1158
fn emit_seq_elt < F > ( & mut self , _idx : uint , f : F ) -> EncodeResult where
1129
- F : FnOnce ( & mut Encoder < ' a , W > ) -> EncodeResult ,
1159
+ F : FnOnce ( & mut Encoder < ' a > ) -> EncodeResult ,
1130
1160
{
1131
1161
1132
1162
try!( self . start_tag ( EsVecElt as uint ) ) ;
@@ -1135,7 +1165,7 @@ pub mod writer {
1135
1165
}
1136
1166
1137
1167
fn emit_map < F > ( & mut self , len : uint , f : F ) -> EncodeResult where
1138
- F : FnOnce ( & mut Encoder < ' a , W > ) -> EncodeResult ,
1168
+ F : FnOnce ( & mut Encoder < ' a > ) -> EncodeResult ,
1139
1169
{
1140
1170
1141
1171
try!( self . start_tag ( EsMap as uint ) ) ;
@@ -1145,7 +1175,7 @@ pub mod writer {
1145
1175
}
1146
1176
1147
1177
fn emit_map_elt_key < F > ( & mut self , _idx : uint , f : F ) -> EncodeResult where
1148
- F : FnOnce ( & mut Encoder < ' a , W > ) -> EncodeResult ,
1178
+ F : FnOnce ( & mut Encoder < ' a > ) -> EncodeResult ,
1149
1179
{
1150
1180
1151
1181
try!( self . start_tag ( EsMapKey as uint ) ) ;
@@ -1154,7 +1184,7 @@ pub mod writer {
1154
1184
}
1155
1185
1156
1186
fn emit_map_elt_val < F > ( & mut self , _idx : uint , f : F ) -> EncodeResult where
1157
- F : FnOnce ( & mut Encoder < ' a , W > ) -> EncodeResult ,
1187
+ F : FnOnce ( & mut Encoder < ' a > ) -> EncodeResult ,
1158
1188
{
1159
1189
try!( self . start_tag ( EsMapVal as uint ) ) ;
1160
1190
try!( f ( self ) ) ;
0 commit comments