1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/* udis86 - libudis86/input.c
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Copyright (c) 2002-2009 Vivek Thampi
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * All rights reserved.
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without modification,
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * are permitted provided that the following conditions are met:
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *     * Redistributions of source code must retain the above copyright notice,
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *       this list of conditions and the following disclaimer.
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *     * Redistributions in binary form must reproduce the above copyright notice,
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *       this list of conditions and the following disclaimer in the documentation
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *       and/or other materials provided with the distribution.
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extern.h"
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "types.h"
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "input.h"
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "udint.h"
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/*
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * inp_init
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *    Initializes the input system.
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static void
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)inp_init(struct ud *u)
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  u->inp_curr = 0;
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  u->inp_fill = 0;
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  u->inp_ctr  = 0;
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  u->inp_end  = 0;
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/* -----------------------------------------------------------------------------
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * inp_buff_hook() - Hook for buffered inputs.
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * -----------------------------------------------------------------------------
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static int
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)inp_buff_hook(struct ud* u)
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (u->inp_buff < u->inp_buff_end)
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return *u->inp_buff++;
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  else  return -1;
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#ifndef __UD_STANDALONE__
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/* -----------------------------------------------------------------------------
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * inp_file_hook() - Hook for FILE inputs.
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * -----------------------------------------------------------------------------
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static int
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)inp_file_hook(struct ud* u)
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return fgetc(u->inp_file);
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif /* __UD_STANDALONE__*/
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/* =============================================================================
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * ud_inp_set_hook() - Sets input hook.
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * =============================================================================
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ud_set_input_hook(register struct ud* u, int (*hook)(struct ud*))
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  u->inp_hook = hook;
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  inp_init(u);
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/* =============================================================================
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * ud_inp_set_buffer() - Set buffer as input.
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * =============================================================================
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ud_set_input_buffer(register struct ud* u, const uint8_t* buf, size_t len)
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  u->inp_hook = inp_buff_hook;
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  u->inp_buff = buf;
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  u->inp_buff_end = buf + len;
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  inp_init(u);
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#ifndef __UD_STANDALONE__
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/* =============================================================================
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * ud_input_set_file() - Set buffer as input.
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * =============================================================================
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ud_set_input_file(register struct ud* u, FILE* f)
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  u->inp_hook = inp_file_hook;
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  u->inp_file = f;
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  inp_init(u);
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif /* __UD_STANDALONE__ */
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/* =============================================================================
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * ud_input_skip() - Skip n input bytes.
109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * =============================================================================
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ud_input_skip(struct ud* u, size_t n)
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  while (n--) {
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    u->inp_hook(u);
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/* =============================================================================
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * ud_input_end() - Test for end of input.
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * =============================================================================
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)int
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ud_input_end(const struct ud* u)
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return (u->inp_curr == u->inp_fill) && u->inp_end;
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/*
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * ud_inp_next
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *    Loads and returns the next byte from input.
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *    inp_curr and inp_fill are pointers to the cache. The program is
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *    written based on the property that they are 8-bits in size, and
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *    will eventually wrap around forming a circular buffer. So, the
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *    size of the cache is 256 in size, kind of unnecessary yet
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *    optimal.
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *    A buffer inp_sess stores the bytes disassembled for a single
141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *    session.
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)uint8_t
144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ud_inp_next(struct ud* u)
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int c = -1;
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  /* if current pointer is not upto the fill point in the
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   * input cache.
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   */
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (u->inp_curr != u->inp_fill) {
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    c = u->inp_cache[ ++u->inp_curr ];
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  /* if !end-of-input, call the input hook and get a byte */
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else if (u->inp_end || (c = u->inp_hook(u)) == -1) {
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    /* end-of-input, mark it as an error, since the decoder,
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)     * expected a byte more.
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)     */
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    UDERR(u, "byte expected, eoi received");
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    /* flag end of input */
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    u->inp_end = 1;
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return 0;
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else {
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    /* increment pointers, we have a new byte.  */
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    u->inp_curr = ++u->inp_fill;
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    /* add the byte to the cache */
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    u->inp_cache[u->inp_fill] = c;
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  /* record bytes input per decode-session. */
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  u->inp_sess[u->inp_ctr++] = c;
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  /* return byte */
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return  (uint8_t) c;
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/*
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)vim: set ts=2 sw=2 expandtab
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)*/
176