OLD | NEW |
1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
3 // https://developers.google.com/protocol-buffers/ | 3 // https://developers.google.com/protocol-buffers/ |
4 // | 4 // |
5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
7 // met: | 7 // met: |
8 // | 8 // |
9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
(...skipping 715 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
726 * @return {number} The decoded zigzag varint. Precision will be lost if the | 726 * @return {number} The decoded zigzag varint. Precision will be lost if the |
727 * integer exceeds 2^53. | 727 * integer exceeds 2^53. |
728 */ | 728 */ |
729 jspb.BinaryDecoder.prototype.readZigzagVarint64 = function() { | 729 jspb.BinaryDecoder.prototype.readZigzagVarint64 = function() { |
730 this.readSplitVarint64_(); | 730 this.readSplitVarint64_(); |
731 return jspb.utils.joinZigzag64(this.tempLow_, this.tempHigh_); | 731 return jspb.utils.joinZigzag64(this.tempLow_, this.tempHigh_); |
732 }; | 732 }; |
733 | 733 |
734 | 734 |
735 /** | 735 /** |
| 736 * Reads a signed, zigzag-encoded 64-bit varint from the binary stream and |
| 737 * returns its valud as a string. |
| 738 * |
| 739 * Zigzag encoding is a modification of varint encoding that reduces the |
| 740 * storage overhead for small negative integers - for more details on the |
| 741 * format, see https://developers.google.com/protocol-buffers/docs/encoding |
| 742 * |
| 743 * @return {string} The decoded signed, zigzag-encoded 64-bit varint as a |
| 744 * string. |
| 745 */ |
| 746 jspb.BinaryDecoder.prototype.readZigzagVarint64String = function() { |
| 747 // TODO(haberman): write lossless 64-bit zig-zag math. |
| 748 var value = this.readZigzagVarint64(); |
| 749 return value.toString(); |
| 750 }; |
| 751 |
| 752 |
| 753 /** |
736 * Reads a raw unsigned 8-bit integer from the binary stream. | 754 * Reads a raw unsigned 8-bit integer from the binary stream. |
737 * | 755 * |
738 * @return {number} The unsigned 8-bit integer read from the binary stream. | 756 * @return {number} The unsigned 8-bit integer read from the binary stream. |
739 */ | 757 */ |
740 jspb.BinaryDecoder.prototype.readUint8 = function() { | 758 jspb.BinaryDecoder.prototype.readUint8 = function() { |
741 var a = this.bytes_[this.cursor_ + 0]; | 759 var a = this.bytes_[this.cursor_ + 0]; |
742 this.cursor_ += 1; | 760 this.cursor_ += 1; |
743 goog.asserts.assert(this.cursor_ <= this.end_); | 761 goog.asserts.assert(this.cursor_ <= this.end_); |
744 return a; | 762 return a; |
745 }; | 763 }; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
784 * Precision will be lost if the integer exceeds 2^53. | 802 * Precision will be lost if the integer exceeds 2^53. |
785 */ | 803 */ |
786 jspb.BinaryDecoder.prototype.readUint64 = function() { | 804 jspb.BinaryDecoder.prototype.readUint64 = function() { |
787 var bitsLow = this.readUint32(); | 805 var bitsLow = this.readUint32(); |
788 var bitsHigh = this.readUint32(); | 806 var bitsHigh = this.readUint32(); |
789 return jspb.utils.joinUint64(bitsLow, bitsHigh); | 807 return jspb.utils.joinUint64(bitsLow, bitsHigh); |
790 }; | 808 }; |
791 | 809 |
792 | 810 |
793 /** | 811 /** |
| 812 * Reads a raw unsigned 64-bit integer from the binary stream. Note that since |
| 813 * Javascript represents all numbers as double-precision floats, there will be |
| 814 * precision lost if the absolute value of the integer is larger than 2^53. |
| 815 * |
| 816 * @return {string} The unsigned 64-bit integer read from the binary stream. |
| 817 */ |
| 818 jspb.BinaryDecoder.prototype.readUint64String = function() { |
| 819 var bitsLow = this.readUint32(); |
| 820 var bitsHigh = this.readUint32(); |
| 821 return jspb.utils.joinUnsignedDecimalString(bitsLow, bitsHigh); |
| 822 }; |
| 823 |
| 824 |
| 825 /** |
794 * Reads a raw signed 8-bit integer from the binary stream. | 826 * Reads a raw signed 8-bit integer from the binary stream. |
795 * | 827 * |
796 * @return {number} The signed 8-bit integer read from the binary stream. | 828 * @return {number} The signed 8-bit integer read from the binary stream. |
797 */ | 829 */ |
798 jspb.BinaryDecoder.prototype.readInt8 = function() { | 830 jspb.BinaryDecoder.prototype.readInt8 = function() { |
799 var a = this.bytes_[this.cursor_ + 0]; | 831 var a = this.bytes_[this.cursor_ + 0]; |
800 this.cursor_ += 1; | 832 this.cursor_ += 1; |
801 goog.asserts.assert(this.cursor_ <= this.end_); | 833 goog.asserts.assert(this.cursor_ <= this.end_); |
802 return (a << 24) >> 24; | 834 return (a << 24) >> 24; |
803 }; | 835 }; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
842 * Precision will be lost if the integer exceeds 2^53. | 874 * Precision will be lost if the integer exceeds 2^53. |
843 */ | 875 */ |
844 jspb.BinaryDecoder.prototype.readInt64 = function() { | 876 jspb.BinaryDecoder.prototype.readInt64 = function() { |
845 var bitsLow = this.readUint32(); | 877 var bitsLow = this.readUint32(); |
846 var bitsHigh = this.readUint32(); | 878 var bitsHigh = this.readUint32(); |
847 return jspb.utils.joinInt64(bitsLow, bitsHigh); | 879 return jspb.utils.joinInt64(bitsLow, bitsHigh); |
848 }; | 880 }; |
849 | 881 |
850 | 882 |
851 /** | 883 /** |
| 884 * Reads a raw signed 64-bit integer from the binary stream and returns it as a |
| 885 * string. |
| 886 * |
| 887 * @return {string} The signed 64-bit integer read from the binary stream. |
| 888 * Precision will be lost if the integer exceeds 2^53. |
| 889 */ |
| 890 jspb.BinaryDecoder.prototype.readInt64String = function() { |
| 891 var bitsLow = this.readUint32(); |
| 892 var bitsHigh = this.readUint32(); |
| 893 return jspb.utils.joinSignedDecimalString(bitsLow, bitsHigh); |
| 894 }; |
| 895 |
| 896 |
| 897 /** |
852 * Reads a 32-bit floating-point number from the binary stream, using the | 898 * Reads a 32-bit floating-point number from the binary stream, using the |
853 * temporary buffer to realign the data. | 899 * temporary buffer to realign the data. |
854 * | 900 * |
855 * @return {number} The float read from the binary stream. | 901 * @return {number} The float read from the binary stream. |
856 */ | 902 */ |
857 jspb.BinaryDecoder.prototype.readFloat = function() { | 903 jspb.BinaryDecoder.prototype.readFloat = function() { |
858 var bitsLow = this.readUint32(); | 904 var bitsLow = this.readUint32(); |
859 var bitsHigh = 0; | 905 var bitsHigh = 0; |
860 return jspb.utils.joinFloat32(bitsLow, bitsHigh); | 906 return jspb.utils.joinFloat32(bitsLow, bitsHigh); |
861 }; | 907 }; |
(...skipping 26 matching lines...) Expand all Loading... |
888 * signed varints. | 934 * signed varints. |
889 * @return {number} The enum value read from the binary stream. | 935 * @return {number} The enum value read from the binary stream. |
890 */ | 936 */ |
891 jspb.BinaryDecoder.prototype.readEnum = function() { | 937 jspb.BinaryDecoder.prototype.readEnum = function() { |
892 return this.readSignedVarint32(); | 938 return this.readSignedVarint32(); |
893 }; | 939 }; |
894 | 940 |
895 | 941 |
896 /** | 942 /** |
897 * Reads and parses a UTF-8 encoded unicode string from the stream. | 943 * Reads and parses a UTF-8 encoded unicode string from the stream. |
898 * The code is inspired by maps.vectortown.parse.StreamedDataViewReader, with | 944 * The code is inspired by maps.vectortown.parse.StreamedDataViewReader. |
899 * the exception that the implementation here does not get confused if it | 945 * Supports codepoints from U+0000 up to U+10FFFF. |
900 * encounters characters longer than three bytes. These characters are ignored | 946 * (http://en.wikipedia.org/wiki/UTF-8). |
901 * though, as they are extremely rare: three UTF-8 bytes cover virtually all | |
902 * characters in common use (http://en.wikipedia.org/wiki/UTF-8). | |
903 * @param {number} length The length of the string to read. | 947 * @param {number} length The length of the string to read. |
904 * @return {string} The decoded string. | 948 * @return {string} The decoded string. |
905 */ | 949 */ |
906 jspb.BinaryDecoder.prototype.readString = function(length) { | 950 jspb.BinaryDecoder.prototype.readString = function(length) { |
907 var bytes = this.bytes_; | 951 var bytes = this.bytes_; |
908 var cursor = this.cursor_; | 952 var cursor = this.cursor_; |
909 var end = cursor + length; | 953 var end = cursor + length; |
910 var chars = []; | 954 var codeUnits = []; |
911 | 955 |
912 while (cursor < end) { | 956 while (cursor < end) { |
913 var c = bytes[cursor++]; | 957 var c = bytes[cursor++]; |
914 if (c < 128) { // Regular 7-bit ASCII. | 958 if (c < 128) { // Regular 7-bit ASCII. |
915 chars.push(c); | 959 codeUnits.push(c); |
916 } else if (c < 192) { | 960 } else if (c < 192) { |
917 // UTF-8 continuation mark. We are out of sync. This | 961 // UTF-8 continuation mark. We are out of sync. This |
918 // might happen if we attempted to read a character | 962 // might happen if we attempted to read a character |
919 // with more than three bytes. | 963 // with more than four bytes. |
920 continue; | 964 continue; |
921 } else if (c < 224) { // UTF-8 with two bytes. | 965 } else if (c < 224) { // UTF-8 with two bytes. |
922 var c2 = bytes[cursor++]; | 966 var c2 = bytes[cursor++]; |
923 chars.push(((c & 31) << 6) | (c2 & 63)); | 967 codeUnits.push(((c & 31) << 6) | (c2 & 63)); |
924 } else if (c < 240) { // UTF-8 with three bytes. | 968 } else if (c < 240) { // UTF-8 with three bytes. |
925 var c2 = bytes[cursor++]; | 969 var c2 = bytes[cursor++]; |
926 var c3 = bytes[cursor++]; | 970 var c3 = bytes[cursor++]; |
927 chars.push(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); | 971 codeUnits.push(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); |
| 972 } else if (c < 248) { // UTF-8 with 4 bytes. |
| 973 var c2 = bytes[cursor++]; |
| 974 var c3 = bytes[cursor++]; |
| 975 var c4 = bytes[cursor++]; |
| 976 // Characters written on 4 bytes have 21 bits for a codepoint. |
| 977 // We can't fit that on 16bit characters, so we use surrogates. |
| 978 var codepoint = ((c & 7) << 18) | ((c2 & 63) << 12) | ((c3 & 63) << 6) | (
c4 & 63); |
| 979 // Surrogates formula from wikipedia. |
| 980 // 1. Subtract 0x10000 from codepoint |
| 981 codepoint -= 0x10000; |
| 982 // 2. Split this into the high 10-bit value and the low 10-bit value |
| 983 // 3. Add 0xD800 to the high value to form the high surrogate |
| 984 // 4. Add 0xDC00 to the low value to form the low surrogate: |
| 985 var low = (codepoint & 1023) + 0xDC00; |
| 986 var high = ((codepoint >> 10) & 1023) + 0xD800; |
| 987 codeUnits.push(high, low) |
928 } | 988 } |
929 } | 989 } |
930 | |
931 // String.fromCharCode.apply is faster than manually appending characters on | 990 // String.fromCharCode.apply is faster than manually appending characters on |
932 // Chrome 25+, and generates no additional cons string garbage. | 991 // Chrome 25+, and generates no additional cons string garbage. |
933 var result = String.fromCharCode.apply(null, chars); | 992 var result = String.fromCharCode.apply(null, codeUnits); |
934 this.cursor_ = cursor; | 993 this.cursor_ = cursor; |
935 return result; | 994 return result; |
936 }; | 995 }; |
937 | 996 |
938 | 997 |
939 /** | 998 /** |
940 * Reads and parses a UTF-8 encoded unicode string (with length prefix) from | 999 * Reads and parses a UTF-8 encoded unicode string (with length prefix) from |
941 * the stream. | 1000 * the stream. |
942 * @return {string} The decoded string. | 1001 * @return {string} The decoded string. |
943 */ | 1002 */ |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
998 var d = bytes[cursor + 3]; | 1057 var d = bytes[cursor + 3]; |
999 var e = bytes[cursor + 4]; | 1058 var e = bytes[cursor + 4]; |
1000 var f = bytes[cursor + 5]; | 1059 var f = bytes[cursor + 5]; |
1001 var g = bytes[cursor + 6]; | 1060 var g = bytes[cursor + 6]; |
1002 var h = bytes[cursor + 7]; | 1061 var h = bytes[cursor + 7]; |
1003 | 1062 |
1004 this.cursor_ += 8; | 1063 this.cursor_ += 8; |
1005 | 1064 |
1006 return String.fromCharCode(a, b, c, d, e, f, g, h); | 1065 return String.fromCharCode(a, b, c, d, e, f, g, h); |
1007 }; | 1066 }; |
OLD | NEW |