PageRenderTime 48ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/javascripts/protobuf.js

http://protobuf-js.googlecode.com/
JavaScript | 134 lines | 122 code | 11 blank | 1 comment | 29 complexity | 414904d16aa50ee4ee9f573f6bd73b5c MD5 | raw file
  1. var Protobuf = $H();
  2. Protobuf.Decoder = Class.create({
  3. initialize: function(description) {
  4. this.description = description;
  5. this.stream = null;
  6. },
  7. readUrl: function(url) {
  8. var req = new XMLHttpRequest();
  9. req.open('GET', url, false);
  10. req.overrideMimeType('text/plain; charset=x-user-defined');
  11. req.send(null);
  12. if (req.status != 200) throw '[' + req.status + ']' + req.statusText;
  13. this.stream = req.responseText;
  14. var bytes = $A();
  15. for (i = 0; i < this.stream.length; i++) {
  16. bytes[i] = this.stream.charCodeAt(i) & 0xff;
  17. }
  18. return bytes;
  19. },
  20. decodeUrl: function(url) {
  21. return this.decode(this.readUrl(url));
  22. },
  23. decode: function(stream) {
  24. this.stream = stream;
  25. var ret = {};
  26. while (this.stream.length != 0) {
  27. var keys = this.readKey();
  28. var type = keys[0], tag = keys[1];
  29. var field = this.description[tag];
  30. if (!field) throw 'Invalid tag: ' + tag;
  31. switch (type) {
  32. case Protobuf.WireType.VARINT:
  33. this.setField(ret, this.readVarint(), field);
  34. break;
  35. case Protobuf.WireType.BIT64:
  36. throw 'Not yet';
  37. break;
  38. case Protobuf.WireType.LENGTH_DELIMITED:
  39. var data = this.readLengthDelimited();
  40. if (field.type == 'string') {
  41. this.setField(ret, String.fromCharCode.apply(String, data), field);
  42. }
  43. else if (field.type == 'bytes') {
  44. this.setField(ret, data, field);
  45. }
  46. else {
  47. var embeddedDescription = this.description[field.type];
  48. this.setField(ret, new Protobuf.Decoder(embeddedDescription).decode(data), field);
  49. }
  50. break;
  51. case Protobuf.WireType.START_GROUP:
  52. case Protobuf.WireType.END_GROUP:
  53. throw 'Have not implemented error';
  54. break;
  55. case Protobuf.WireType.BIT32:
  56. throw 'Not yet';
  57. break;
  58. default:
  59. throw 'Unknown WireType: ' + type;
  60. }
  61. }
  62. return ret;
  63. },
  64. setField: function(obj, value, field) {
  65. if (field.rule == 'repeated') {
  66. if (!obj[field.name]) obj[field.name] = [];
  67. obj[field.name].push(value);
  68. }
  69. else {
  70. obj[field.name] = value;
  71. }
  72. },
  73. readKey: function() {
  74. var byte = this.stream.shift();
  75. var type = byte & 0x07;
  76. var tag = (byte & 0x7F) >>> 3;
  77. var first = true;
  78. if ((byte >> 7) != 0) {
  79. byte = this.stream.shift();
  80. tag = ((byte & 0x7F) << (first ? 4 : 7)) | tag;
  81. }
  82. return [type, tag];
  83. },
  84. readVarint: function() {
  85. var ret = 0;
  86. for (var i = 0; ; i++) {
  87. var byte = this.stream.shift();
  88. ret |= (byte & 0x7F) << (7 * i);
  89. if ((byte >> 7) == 0) break;
  90. }
  91. return ret;
  92. },
  93. readLengthDelimited: function() {
  94. var length = this.readVarint();
  95. var ret = $A();
  96. for (var i = 0; i < length; i++) {
  97. ret.push(this.stream.shift());
  98. }
  99. return ret;
  100. },
  101. // Methods for debug
  102. toBinaryString: function(val, figure) {
  103. var ret = '';
  104. var block = function() {
  105. ret = '' + (val & 1) + ret;
  106. val >>>= 1;
  107. };
  108. if (figure == null) {
  109. while (val != 0) block();
  110. } else {
  111. for (var i = 0; i < 8; i++) block();
  112. }
  113. return ret;
  114. },
  115. });
  116. Protobuf.WireType = {
  117. VARINT : 0,
  118. BIT64 : 1,
  119. LENGTH_DELIMITED : 2,
  120. START_GROUP : 3,
  121. END_GROUP : 4,
  122. BIT32 : 5,
  123. };