<commit_before>
util = require '../util'
{SlicerBuffer} = require './buffer'
C = require('../const').openpgp
{KeyMaterial} = require './packet/keymaterial'
{Signature} = require './packet/signature'
{SEIPD,PKESK} = require './packet/sess'
{UserID} = require './packet/userid'
{Generic} = require './packet/generic'
{inspect} = require 'util'

#==================================================================================================

class MessageParser 
  constructor : (@slice) ->
  parse : () -> (@parse_packet() while @slice.rem())
  parse_packet : () -> (new PacketParser @slice).parse()
   
#==================================================================================================

class PacketParser

  #----------------

  constructor : (@slice) ->
    @body = null
    @real_packet_len = null
    @tag = null
    @len = null
    @header_len = null

  #----------------

  parse_header : () ->
    @parse_tag_and_len()
    @header_len or= @slice.offset()
    console.log "reading packet length -> #{@len}"
    console.log "rem -> #{@slice.rem()}"
    @body or= new SlicerBuffer @slice.read_buffer @len
    @real_packet_len or= @len
    @slice.unclamp()

  #----------------

  parse : () ->
    console.log "1. lefties -> #{@slice.rem()}"
    @parse_header()
    console.log "2. lefties -> #{@slice.rem()}"
    ret = @parse_body()
    ret

  #----------------

  parse_body : () ->
    pt = C.packet_tags
    sb = @body
    raw = sb.peek_rest_to_buffer()
    packet = switch @tag
      when pt.PKESK         then PKESK.parse sb
      when pt.secret_key    then KeyMaterial.parse_private_key sb, { subkey : false }
      when pt.secret_subkey then KeyMaterial.parse_private_key sb, { subkey : true }
      when pt.public_key    then KeyMaterial.parse_public_key sb,  { subkey : false }
      when pt.public_subkey then KeyMaterial.parse_public_key sb,  { subkey : true }
      when pt.signature     then Signature.parse sb
      when pt.userid        then UserID.parse sb
      when pt.SEIPD         then SEIPD.parse sb
      else                  new Generic @tag, sb # throw new Error "Unknown packet tag: #{@tag}"
    packet.set { @tag, @real_packet_len, @header_len, raw }
    packet

  #----------------

  parse_tag_and_len : () ->
    if @slice.len() < 2 or ((c = @slice.read_uint8()) & 0x80) is 0
      throw new Error "This doesn't look like a binary PGP packet"
    if (c & 0x40) is 0 then @parse_tag_and_len_old(c) else @parse_tag_and_len_new(c)

  #----------------

  parse_tag_and_len_old : (c) ->
    console.log "in parse_tag_and_len old! #{@slice.rem()}"
    @tag = (c & 0x3f) >> 2
    @len = switch (c & 0x03)
      when 0 then @slice.read_uint8()
      when 1 then @slice.read_uint16()
      when 2 then @slice.read_uint32()
      when 3 then @slice.rem()
    console.log "tag -> #{@tag}"
    console.log "len -> #{@len}"
    console.log "rem -> #{@slice.rem()}"

  #----------------

  parse_tag_and_len_new : (c) ->
    console.log "in parse tag and len new..."
    @tag = (c & 0x3f)
    @parse_tag_len_new()
    console.log "tag -> #{@tag}"
    console.log "len -> #{@len}"

  #----------------

  parse_tag_len_new : () -> 
    go = true
    segments = []
    @len = 0
    lastlen = 0
    while go
      go = false
      c = @slice.read_uint8()

      lastlen = if (c < 192) then c
      else if (c is 255) then @slice.read_uint32()
      else if (c < 224) 
        d = @slice.read_uint8()
        ((c - 192) << 8) + (d + 192)
      else
        @header_len or= @slice.offset()
        packet_length = 1 << (c & 0x1f)
        segments.push @slice.read_buffer packet_length 
        go = true
        packet_length

      @len += lastlen<commit_msg>clean up debug<commit_after>
util = require '../util'
{SlicerBuffer} = require './buffer'
C = require('../const').openpgp
{KeyMaterial} = require './packet/keymaterial'
{Signature} = require './packet/signature'
{SEIPD,PKESK} = require './packet/sess'
{UserID} = require './packet/userid'
{Generic} = require './packet/generic'
{inspect} = require 'util'

#==================================================================================================

class MessageParser 
  constructor : (@slice) ->
  parse : () -> (@parse_packet() while @slice.rem())
  parse_packet : () -> (new PacketParser @slice).parse()
   
#==================================================================================================

class PacketParser

  #----------------

  constructor : (@slice) ->
    @body = null
    @real_packet_len = null
    @tag = null
    @len = null
    @header_len = null

  #----------------

  parse_header : () ->
    @parse_tag_and_len()
    @header_len or= @slice.offset()
    @body or= new SlicerBuffer @slice.read_buffer @len
    @real_packet_len or= @len
    @slice.unclamp()

  #----------------

  parse : () ->
    @parse_header()
    ret = @parse_body()
    ret

  #----------------

  parse_body : () ->
    pt = C.packet_tags
    sb = @body
    raw = sb.peek_rest_to_buffer()
    packet = switch @tag
      when pt.PKESK         then PKESK.parse sb
      when pt.secret_key    then KeyMaterial.parse_private_key sb, { subkey : false }
      when pt.secret_subkey then KeyMaterial.parse_private_key sb, { subkey : true }
      when pt.public_key    then KeyMaterial.parse_public_key sb,  { subkey : false }
      when pt.public_subkey then KeyMaterial.parse_public_key sb,  { subkey : true }
      when pt.signature     then Signature.parse sb
      when pt.userid        then UserID.parse sb
      when pt.SEIPD         then SEIPD.parse sb
      else                  new Generic @tag, sb # throw new Error "Unknown packet tag: #{@tag}"
    packet.set { @tag, @real_packet_len, @header_len, raw }
    packet

  #----------------

  parse_tag_and_len : () ->
    if @slice.len() < 2 or ((c = @slice.read_uint8()) & 0x80) is 0
      throw new Error "This doesn't look like a binary PGP packet"
    if (c & 0x40) is 0 then @parse_tag_and_len_old(c) else @parse_tag_and_len_new(c)

  #----------------

  parse_tag_and_len_old : (c) ->
    @tag = (c & 0x3f) >> 2
    @len = switch (c & 0x03)
      when 0 then @slice.read_uint8()
      when 1 then @slice.read_uint16()
      when 2 then @slice.read_uint32()
      when 3 then @slice.rem()

  #----------------

  parse_tag_and_len_new : (c) ->
    @tag = (c & 0x3f)
    @parse_tag_len_new()

  #----------------

  parse_tag_len_new : () -> 
    go = true
    segments = []
    @len = 0
    lastlen = 0
    while go
      go = false
      c = @slice.read_uint8()

      lastlen = if (c < 192) then c
      else if (c is 255) then @slice.read_uint32()
      else if (c < 224) 
        d = @slice.read_uint8()
        ((c - 192) << 8) + (d + 192)
      else
        @header_len or= @slice.offset()
        packet_length = 1 << (c & 0x1f)
        segments.push @slice.read_buffer packet_length 
        go = true
        packet_length

      @len += lastlen
{'fraction_non_alphanumeric': 0.21818181818181817, 'fraction_numerical': 0.015295815295815297, 'mean_word_length': 2.2895111532985286, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 38, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5181894', 'n_tokens_mistral': 2372, 'n_tokens_neox': 2222, 'n_words': 574}