]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
(sexp_get_char): Use the nettle_armor
authorNiels Möller <nisse@lysator.liu.se>
Thu, 31 Oct 2002 10:42:12 +0000 (11:42 +0100)
committerNiels Möller <nisse@lysator.liu.se>
Thu, 31 Oct 2002 10:42:12 +0000 (11:42 +0100)
interface for decoding.
(sexp_input_start_coding): New function.
(sexp_input_end_coding): New function.
(sexp_get_base64_string): Rewrote to use sexp_input_start_coding
and sexp_input_end_coding.
(sexp_get_token): Generate SEXP_TRANSPORT_START tokens.
(sexp_convert_list): Lists are ended only by SEXP_LIST_END.
(sexp_convert_item): Implemented transport mode, using
sexp_input_start_coding and sexp_input_end_coding.

Rev: src/nettle/examples/sexp-conv.c:1.11

examples/sexp-conv.c

index 5ae47b1daeeba7fbd9ae73dc08a480af7f2e7397..a1283b87eac514097a5a027deb206f4e6dbb13b9 100644 (file)
@@ -52,27 +52,20 @@ enum sexp_token
     SEXP_LIST_START,
     SEXP_LIST_END,
     SEXP_TRANSPORT_START,
-    SEXP_TRANSPORT_END,
+    SEXP_CODING_END,
     SEXP_EOF,
   };
 
-enum sexp_coding
-  {
-    SEXP_PLAIN,
-    SEXP_BASE64,
-    SEXP_HEX,
-  };
-
 struct sexp_input
 {
   FILE *f;
 
-  enum sexp_coding coding;
-  /* Used in transport mode */
+  const struct nettle_armor *coding;
+
   union {
     struct base64_decode_ctx base64;
     struct base16_decode_ctx hex;
-  };
+  } state;
 
   /* Terminator for current coding */
   uint8_t terminator;
@@ -91,7 +84,7 @@ static void
 sexp_input_init(struct sexp_input *input, FILE *f)
 {
   input->f = f;
-  input->coding = SEXP_PLAIN;
+  input->coding = NULL;
   input->level = 0;
 
   nettle_buffer_init(&input->string);
@@ -146,46 +139,68 @@ sexp_get_raw_char(struct sexp_input *input, uint8_t *out)
 static int
 sexp_get_char(struct sexp_input *input, uint8_t *out)
 {
-  switch (input->coding)
-    {
-    case SEXP_BASE64:
-      for (;;)
-       {
-         int done;
-         uint8_t c;
-         
-         if (!sexp_get_raw_char(input, &c))
-           die("Unexpected end of file in base64 data.\n");
-
-         if (c == '}')
-           {
-             if (base64_decode_final(&input->base64))
-               {
-                 input->token = SEXP_TRANSPORT_END;
-                 return 0;
-               }
-             else
-               die("Invalid base64 data.\n");
-           }
+  if (input->coding)
+    for (;;)
+      {
+       int done;
+       uint8_t c;
+       
+       if (!sexp_get_raw_char(input, &c))
+         die("Unexpected end of file in coded data.\n");
 
-         done = base64_decode_single(&input->base64, out, c);
-         if (done)
-           return 1;
-       }
-    case SEXP_PLAIN:
+       if (c == input->terminator)
+         {
+           if (input->coding->decode_final(&input->state))
+             {
+               input->token = SEXP_CODING_END;
+               return 0;
+             }
+           else
+             die("Invalid coded data.\n");
+         }
+       done = 1;
+       
+       if (!input->coding->decode_update(&input->state, &done, out, 1, &c))
+         die("Invalid coded data.\n");
+         
+       if (done)
+         return 1;
+      }
+  else
+    {
       if (sexp_get_raw_char(input, out))
        return 1;
       
       input->token = SEXP_EOF;
       return 0;
+    }
+}
 
-    case SEXP_HEX:
-      /* Not yet implemented */
-      abort();
+static unsigned
+sexp_input_start_coding(struct sexp_input *input,
+                       const struct nettle_armor *coding,
+                       uint8_t terminator)
+{
+  unsigned old_level = input->level;
+  
+  assert(!input->coding);
+  
+  input->coding = coding;
+  input->coding->decode_init(&input->state);
+  input->terminator = terminator;
+  input->level = 0;
 
-    default:
-      abort();
-    }
+  return old_level;
+}
+
+static void
+sexp_input_end_coding(struct sexp_input *input,
+                     unsigned old_level)
+{
+  assert(input->coding);
+
+  input->coding = NULL;
+  input->level = old_level;
 }
 
 static const char
@@ -214,6 +229,7 @@ token_chars[0x80] =
 static uint8_t
 sexp_get_token_char(struct sexp_input *input)
 {
+  /* FIXME: Use sexp_get_char */
   int c = getc(input->f);
   if (c >= 0 && TOKEN_CHAR(c))
     return c;
@@ -273,7 +289,7 @@ sexp_get_quoted_string(struct sexp_input *input)
 {
   uint8_t c;
 
-  assert(input->coding == SEXP_PLAIN);
+  assert(!input->coding);
   
   while (sexp_get_quoted_char(input, &c))
     if (!NETTLE_BUFFER_PUTC(&input->string, c))
@@ -290,47 +306,31 @@ sexp_get_hex_string(struct sexp_input *input)
 static void
 sexp_get_base64_string(struct sexp_input *input)
 {
-  struct base64_decode_ctx ctx;
-
-  assert(input->coding == SEXP_PLAIN);
+  unsigned old_level 
+    = sexp_input_start_coding(input, &nettle_base64, '|');
 
-  base64_decode_init(&ctx);
-  
   for (;;)
     {
       uint8_t c;
-      uint8_t decoded;
       
       if (!sexp_get_char(input, &c))
-       die("Unexpected end of file in base64 string.\n");
-
-      if (c == '|')
        {
-         if (!base64_decode_final(&ctx))
-           die("Invalid base64 string.\n");
+         if (input->token != SEXP_CODING_END)
+           die("Unexpected end of file in base64 string.\n");
+
+         sexp_input_end_coding(input, old_level);
          return;
        }
       
-      switch(base64_decode_single(&ctx, &decoded, c))
-       {
-       case 0:
-         break;
-       case 1:
-         if (!NETTLE_BUFFER_PUTC(&input->string, decoded))
-           die("Virtual memory exhasuted.\n");
-         break;
-       case -1:
-         die("Invalid base64 string.\n");
-       default:
-         abort();
-       }
+      if (!NETTLE_BUFFER_PUTC(&input->string, c))
+       die("Virtual memory exhasuted.\n");
     }
 }
 
 static void
 sexp_get_token_string(struct sexp_input *input, uint8_t c)
 {
-  assert(input->coding == SEXP_PLAIN);
+  assert(!input->coding);
 
   if (!TOKEN_CHAR(c) || ! NETTLE_BUFFER_PUTC(&input->string, c))
     die("Invalid token.\n");
@@ -464,6 +464,10 @@ sexp_get_token(struct sexp_input *input, enum sexp_mode mode)
          input->token = SEXP_DISPLAY_END;
          return;
 
+       case '{':
+         input->token = SEXP_TRANSPORT_START;
+         return;
+         
        case ' ':  /* SPC, TAB, LF, CR */
        case '\t':
        case '\n':
@@ -757,10 +761,7 @@ sexp_convert_list(struct sexp_input *input, enum sexp_mode mode_in,
     {
       sexp_get_token(input, mode_in);
   
-      /* Check for end of list */
-      if (input->token == SEXP_LIST_END
-         || input->token == SEXP_EOF
-         || input->token == SEXP_TRANSPORT_END)
+      if (input->token == SEXP_LIST_END)
        return;
 
       if (mode_out == SEXP_ADVANCED)
@@ -861,6 +862,7 @@ sexp_convert_item(struct sexp_input *input, enum sexp_mode mode_in,
     case SEXP_STRING:
       sexp_put_string(output, mode_out, &input->string);
       break;
+
     case SEXP_DISPLAY_START:
       sexp_put_display_start(output);
       sexp_convert_string(input, mode_in, output, mode_out);
@@ -874,28 +876,19 @@ sexp_convert_item(struct sexp_input *input, enum sexp_mode mode_in,
        die("Base64 not allowed in canonical mode.\n");
       else
        {
-         unsigned old_level = input->level;
-         assert(input->coding == SEXP_PLAIN);
+         unsigned old_level
+           = sexp_input_start_coding(input, &nettle_base64, '}');
+         sexp_get_token(input, SEXP_CANONICAL);
          
-         input->coding = SEXP_BASE64;
-         input->level = 0;
-
-         base64_decode_init(&input->base64);
-
-         /* FIXME: sexp_convert_list is wrong. */
-         sexp_convert_list(input, SEXP_CANONICAL, output, mode_out, indent);
+         sexp_convert_item(input, SEXP_CANONICAL, output, mode_out, indent);
+         sexp_skip_token(input, SEXP_CANONICAL, SEXP_CODING_END);
+         sexp_input_end_coding(input, old_level);
          
-         input->coding = SEXP_PLAIN;
-         input->level = old_level;
          break;
        }
-    case SEXP_TRANSPORT_END:
-      /* FIXME: Should be moved do sexp_convert_transport */
-      if ( (input->coding != SEXP_BASE64)
-          || input->level || !base64_decode_final(&input->base64))
-       die("Invalid base64.\n");
+    case SEXP_CODING_END:
+      die("Unexpected end of coding.\n");
 
-      break;
     default:
       die("Syntax error.\n");
     }