1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  ftstream.c                                                             */
4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
5049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*    I/O stream support (body).                                           */
6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
7ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki/*  Copyright 2000-2015 by                                                 */
8049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
10049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  This file is part of the FreeType project, and may only be used,       */
11049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  modified, and distributed under the terms of the FreeType project      */
12049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  this file you indicate that you have read the license and              */
14049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  understand and accept it fully.                                        */
15049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
16049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
17049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
18049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
19049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <ft2build.h>
20049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_STREAM_H
21049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_DEBUG_H
22049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
23049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
24049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
25049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
26049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
27049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
28049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* messages during execution.                                            */
29049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
30049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_COMPONENT
31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT  trace_stream
32049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
35049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Stream_OpenMemory( FT_Stream       stream,
36049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        const FT_Byte*  base,
37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_ULong        size )
38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->base   = (FT_Byte*) base;
40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->size   = size;
41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->pos    = 0;
42ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    stream->cursor = NULL;
43ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    stream->read   = NULL;
44ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    stream->close  = NULL;
45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
47049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
49049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Stream_Close( FT_Stream  stream )
50049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( stream && stream->close )
52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      stream->close( stream );
53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Stream_Seek( FT_Stream  stream,
58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_ULong   pos )
59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error  error = FT_Err_Ok;
61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( stream->read )
64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( stream->read( stream, pos, 0, 0 ) )
66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
67295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_ERROR(( "FT_Stream_Seek:"
68295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                   " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   pos, stream->size ));
70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
71727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        error = FT_THROW( Invalid_Stream_Operation );
72049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* note that seeking to the first position after the file is valid */
75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( pos > stream->size )
76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
77295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_ERROR(( "FT_Stream_Seek:"
78295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                 " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 pos, stream->size ));
80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
81727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_THROW( Invalid_Stream_Operation );
82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
84295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    if ( !error )
85295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      stream->pos = pos;
86295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
90049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Stream_Skip( FT_Stream  stream,
93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Long    distance )
94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( distance < 0 )
96727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Stream_Operation );
97049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
98ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    return FT_Stream_Seek( stream, stream->pos + (FT_ULong)distance );
99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
102ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  FT_BASE_DEF( FT_ULong )
103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Stream_Pos( FT_Stream  stream )
104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return stream->pos;
106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Stream_Read( FT_Stream  stream,
111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Byte*   buffer,
112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_ULong   count )
113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Stream_ReadAt( stream, stream->pos, buffer, count );
115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Stream_ReadAt( FT_Stream  stream,
120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_ULong   pos,
121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Byte*   buffer,
122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_ULong   count )
123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error  error = FT_Err_Ok;
125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong  read_bytes;
126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( pos >= stream->size )
129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
130295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_ERROR(( "FT_Stream_ReadAt:"
131295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                 " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 pos, stream->size ));
133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
134727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Stream_Operation );
135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( stream->read )
138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      read_bytes = stream->read( stream, pos, buffer, count );
139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      read_bytes = stream->size - pos;
142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( read_bytes > count )
143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        read_bytes = count;
144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_MEM_COPY( buffer, stream->base + pos, read_bytes );
146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->pos = pos + read_bytes;
149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( read_bytes < count )
151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
152295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_ERROR(( "FT_Stream_ReadAt:"
153295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                 " invalid read; expected %lu bytes, got %lu\n",
154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 count, read_bytes ));
155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
156727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_THROW( Invalid_Stream_Operation );
157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_ULong )
164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Stream_TryRead( FT_Stream  stream,
165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Byte*   buffer,
166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_ULong   count )
167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong  read_bytes = 0;
169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( stream->pos >= stream->size )
172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( stream->read )
175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      read_bytes = stream->read( stream, stream->pos, buffer, count );
176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      read_bytes = stream->size - stream->pos;
179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( read_bytes > count )
180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        read_bytes = count;
181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_MEM_COPY( buffer, stream->base + stream->pos, read_bytes );
183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->pos += read_bytes;
186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return read_bytes;
189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Stream_ExtractFrame( FT_Stream  stream,
194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_ULong   count,
195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Byte**  pbytes )
196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error  error;
198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Stream_EnterFrame( stream, count );
201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !error )
202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *pbytes = (FT_Byte*)stream->cursor;
204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* equivalent to FT_Stream_ExitFrame(), with no memory block release */
206ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      stream->cursor = NULL;
207ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      stream->limit  = NULL;
208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Stream_ReleaseFrame( FT_Stream  stream,
216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Byte**  pbytes )
217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
218295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    if ( stream && stream->read )
219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Memory  memory = stream->memory;
221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_DEBUG_MEMORY
223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_mem_free( memory, *pbytes );
224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *pbytes = NULL;
225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else
226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( *pbytes );
227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
229ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    *pbytes = NULL;
230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Stream_EnterFrame( FT_Stream  stream,
235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_ULong   count )
236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error  error = FT_Err_Ok;
238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong  read_bytes;
239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* check for nested frame access */
242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( stream && stream->cursor == 0 );
243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( stream->read )
245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* allocate the frame in memory */
247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Memory  memory = stream->memory;
248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
249aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
250aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      /* simple sanity check */
251aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( count > stream->size )
252aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      {
253aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        FT_ERROR(( "FT_Stream_EnterFrame:"
254aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                   " frame size (%lu) larger than stream size (%lu)\n",
255aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                   count, stream->size ));
256aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
257727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        error = FT_THROW( Invalid_Stream_Operation );
258aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        goto Exit;
259aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      }
260aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_DEBUG_MEMORY
262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* assume _ft_debug_file and _ft_debug_lineno are already set */
263ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      stream->base = (unsigned char*)ft_mem_qalloc( memory,
264ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki                                                    (FT_Long)count,
265ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki                                                    &error );
266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else
269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_QALLOC( stream->base, count ) )
270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* read it */
273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      read_bytes = stream->read( stream, stream->pos,
274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 stream->base, count );
275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( read_bytes < count )
276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
277295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_ERROR(( "FT_Stream_EnterFrame:"
278295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                   " invalid read; expected %lu bytes, got %lu\n",
279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   count, read_bytes ));
280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FREE( stream->base );
282727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        error = FT_THROW( Invalid_Stream_Operation );
283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      stream->cursor = stream->base;
285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      stream->limit  = stream->cursor + count;
286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      stream->pos   += read_bytes;
287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* check current and new position */
291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( stream->pos >= stream->size        ||
292aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich           stream->size - stream->pos < count )
293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
294295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_ERROR(( "FT_Stream_EnterFrame:"
295295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                   " invalid i/o; pos = 0x%lx, count = %lu, size = 0x%lx\n",
296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   stream->pos, count, stream->size ));
297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
298727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        error = FT_THROW( Invalid_Stream_Operation );
299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* set cursor */
303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      stream->cursor = stream->base + stream->pos;
304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      stream->limit  = stream->cursor + count;
305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      stream->pos   += count;
306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Stream_ExitFrame( FT_Stream  stream )
315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* IMPORTANT: The assertion stream->cursor != 0 was removed, given    */
317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*            that it is possible to access a frame of length 0 in    */
318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*            some weird fonts (usually, when accessing an array of   */
319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*            0 records, like in some strange kern tables).           */
320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                    */
321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*  In this case, the loader code handles the 0-length table          */
322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*  gracefully; however, stream.cursor is really set to 0 by the      */
323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*  FT_Stream_EnterFrame() call, and this is not an error.            */
324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                    */
325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( stream );
326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( stream->read )
328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Memory  memory = stream->memory;
330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_DEBUG_MEMORY
332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_mem_free( memory, stream->base );
333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      stream->base = NULL;
334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else
335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( stream->base );
336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
338ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    stream->cursor = NULL;
339ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    stream->limit  = NULL;
340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Char )
344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Stream_GetChar( FT_Stream  stream )
345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Char  result;
347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( stream && stream->cursor );
350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    result = 0;
352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( stream->cursor < stream->limit )
353ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      result = (FT_Char)*stream->cursor++;
354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
359aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_BASE_DEF( FT_UShort )
360aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_Stream_GetUShort( FT_Stream  stream )
361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
362ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_Byte*   p;
363ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_UShort  result;
364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( stream && stream->cursor );
367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    result         = 0;
369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    p              = stream->cursor;
370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( p + 1 < stream->limit )
371aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner      result       = FT_NEXT_USHORT( p );
372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->cursor = p;
373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
378aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_BASE_DEF( FT_UShort )
379aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_Stream_GetUShortLE( FT_Stream  stream )
380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
381ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_Byte*   p;
382ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_UShort  result;
383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( stream && stream->cursor );
386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    result         = 0;
388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    p              = stream->cursor;
389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( p + 1 < stream->limit )
390aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner      result       = FT_NEXT_USHORT_LE( p );
391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->cursor = p;
392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
397aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_BASE_DEF( FT_ULong )
398aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_Stream_GetUOffset( FT_Stream  stream )
399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  p;
401ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_ULong  result;
402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( stream && stream->cursor );
405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    result         = 0;
407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    p              = stream->cursor;
408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( p + 2 < stream->limit )
409aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner      result       = FT_NEXT_UOFF3( p );
410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->cursor = p;
411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
415aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_BASE_DEF( FT_ULong )
416aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_Stream_GetULong( FT_Stream  stream )
417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  p;
419ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_ULong  result;
420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( stream && stream->cursor );
423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    result         = 0;
425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    p              = stream->cursor;
426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( p + 3 < stream->limit )
427aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner      result       = FT_NEXT_ULONG( p );
428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->cursor = p;
429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
433aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_BASE_DEF( FT_ULong )
434aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_Stream_GetULongLE( FT_Stream  stream )
435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  p;
437ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_ULong  result;
438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( stream && stream->cursor );
441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    result         = 0;
443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    p              = stream->cursor;
444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( p + 3 < stream->limit )
445aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner      result       = FT_NEXT_ULONG_LE( p );
446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->cursor = p;
447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Char )
452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Stream_ReadChar( FT_Stream  stream,
453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Error*  error )
454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte  result = 0;
456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( stream );
459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *error = FT_Err_Ok;
461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( stream->read )
463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( stream->read( stream, stream->pos, &result, 1L ) != 1L )
465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Fail;
466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( stream->pos < stream->size )
470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = stream->base[stream->pos];
471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Fail;
473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->pos++;
475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
476ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    return (FT_Char)result;
477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
479727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    *error = FT_THROW( Invalid_Stream_Operation );
480295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_ERROR(( "FT_Stream_ReadChar:"
481295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner               " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               stream->pos, stream->size ));
483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
488aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_BASE_DEF( FT_UShort )
489aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_Stream_ReadUShort( FT_Stream  stream,
490ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki                        FT_Error*  error )
491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
492ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_Byte    reads[2];
493ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_Byte*   p      = 0;
494ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_UShort  result = 0;
495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( stream );
498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *error = FT_Err_Ok;
500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( stream->pos + 1 < stream->size )
502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( stream->read )
504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( stream->read( stream, stream->pos, reads, 2L ) != 2L )
506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Fail;
507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        p = reads;
509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        p = stream->base + stream->pos;
512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( p )
514aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner        result = FT_NEXT_USHORT( p );
515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->pos += 2;
520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
524727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    *error = FT_THROW( Invalid_Stream_Operation );
525aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_ERROR(( "FT_Stream_ReadUShort:"
526295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner               " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               stream->pos, stream->size ));
528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
533aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_BASE_DEF( FT_UShort )
534aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_Stream_ReadUShortLE( FT_Stream  stream,
535ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki                          FT_Error*  error )
536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
537ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_Byte    reads[2];
538ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_Byte*   p      = 0;
539ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_UShort  result = 0;
540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( stream );
543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *error = FT_Err_Ok;
545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( stream->pos + 1 < stream->size )
547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( stream->read )
549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( stream->read( stream, stream->pos, reads, 2L ) != 2L )
551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Fail;
552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        p = reads;
554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        p = stream->base + stream->pos;
557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( p )
559aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner        result = FT_NEXT_USHORT_LE( p );
560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->pos += 2;
565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
569727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    *error = FT_THROW( Invalid_Stream_Operation );
570aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_ERROR(( "FT_Stream_ReadUShortLE:"
571295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner               " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               stream->pos, stream->size ));
573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
578aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_BASE_DEF( FT_ULong )
579aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_Stream_ReadUOffset( FT_Stream  stream,
580ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki                         FT_Error*  error )
581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte   reads[3];
583ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_Byte*  p      = 0;
584ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_ULong  result = 0;
585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( stream );
588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *error = FT_Err_Ok;
590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( stream->pos + 2 < stream->size )
592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( stream->read )
594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if (stream->read( stream, stream->pos, reads, 3L ) != 3L )
596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Fail;
597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        p = reads;
599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        p = stream->base + stream->pos;
602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( p )
604aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner        result = FT_NEXT_UOFF3( p );
605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->pos += 3;
610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
614727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    *error = FT_THROW( Invalid_Stream_Operation );
615aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_ERROR(( "FT_Stream_ReadUOffset:"
616295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner               " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               stream->pos, stream->size ));
618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
623aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_BASE_DEF( FT_ULong )
624aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_Stream_ReadULong( FT_Stream  stream,
625ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki                       FT_Error*  error )
626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte   reads[4];
628ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_Byte*  p      = 0;
629ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_ULong  result = 0;
630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( stream );
633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *error = FT_Err_Ok;
635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( stream->pos + 3 < stream->size )
637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( stream->read )
639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( stream->read( stream, stream->pos, reads, 4L ) != 4L )
641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Fail;
642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        p = reads;
644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        p = stream->base + stream->pos;
647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( p )
649aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner        result = FT_NEXT_ULONG( p );
650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->pos += 4;
655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
659727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    *error = FT_THROW( Invalid_Stream_Operation );
660aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_ERROR(( "FT_Stream_ReadULong:"
661295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner               " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
662295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner               stream->pos, stream->size ));
663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
668aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_BASE_DEF( FT_ULong )
669aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_Stream_ReadULongLE( FT_Stream  stream,
670ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki                         FT_Error*  error )
671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte   reads[4];
673ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_Byte*  p      = 0;
674ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_ULong  result = 0;
675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( stream );
678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *error = FT_Err_Ok;
680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( stream->pos + 3 < stream->size )
682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( stream->read )
684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( stream->read( stream, stream->pos, reads, 4L ) != 4L )
686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Fail;
687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        p = reads;
689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        p = stream->base + stream->pos;
692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( p )
694aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner        result = FT_NEXT_ULONG_LE( p );
695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->pos += 4;
700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
704727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    *error = FT_THROW( Invalid_Stream_Operation );
705aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_ERROR(( "FT_Stream_ReadULongLE:"
706295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner               " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
707295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner               stream->pos, stream->size ));
708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Stream_ReadFields( FT_Stream              stream,
715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        const FT_Frame_Field*  fields,
716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        void*                  structure )
717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error  error;
719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Bool   frame_accessed = 0;
7200a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    FT_Byte*  cursor;
721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
722727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
723ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    if ( !fields )
724727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
726ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    if ( !stream )
727ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      return FT_THROW( Invalid_Stream_Handle );
728ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
7290a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    cursor = stream->cursor;
7300a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Err_Ok;
732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    do
733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ULong  value;
735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int    sign_shift;
736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Byte*  p;
737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      switch ( fields->value )
740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_start:  /* access a new frame */
742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = FT_Stream_EnterFrame( stream, fields->offset );
743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        frame_accessed = 1;
747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        cursor         = stream->cursor;
748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        fields++;
749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        continue;  /* loop! */
750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_bytes:  /* read a byte sequence */
752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_skip:   /* skip some bytes      */
753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_UInt  len = fields->size;
755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( cursor + len > stream->limit )
758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
759727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            error = FT_THROW( Invalid_Stream_Operation );
760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Exit;
761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( fields->value == ft_frame_bytes )
764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            p = (FT_Byte*)structure + fields->offset;
766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_MEM_COPY( p, cursor, len );
767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          cursor += len;
769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          fields++;
770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          continue;
771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_byte:
774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_schar:  /* read a single byte */
775727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        value = FT_NEXT_BYTE( cursor );
776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        sign_shift = 24;
777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_short_be:
780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_ushort_be:  /* read a 2-byte big-endian short */
781727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        value = FT_NEXT_USHORT( cursor) ;
782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        sign_shift = 16;
783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_short_le:
786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_ushort_le:  /* read a 2-byte little-endian short */
787727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        value = FT_NEXT_USHORT_LE( cursor );
788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        sign_shift = 16;
789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_long_be:
792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_ulong_be:  /* read a 4-byte big-endian long */
793727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        value = FT_NEXT_ULONG( cursor );
794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        sign_shift = 0;
795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_long_le:
798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_ulong_le:  /* read a 4-byte little-endian long */
799727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        value = FT_NEXT_ULONG_LE( cursor );
800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        sign_shift = 0;
801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_off3_be:
804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_uoff3_be:  /* read a 3-byte big-endian long */
805727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        value = FT_NEXT_UOFF3( cursor );
806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        sign_shift = 8;
807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_off3_le:
810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_uoff3_le:  /* read a 3-byte little-endian long */
811727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        value = FT_NEXT_UOFF3_LE( cursor );
812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        sign_shift = 8;
813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      default:
816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* otherwise, exit the loop */
817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        stream->cursor = cursor;
818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* now, compute the signed value is necessary */
822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( fields->value & FT_FRAME_OP_SIGNED )
823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        value = (FT_ULong)( (FT_Int32)( value << sign_shift ) >> sign_shift );
824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* finally, store the value in the object */
826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      p = (FT_Byte*)structure + fields->offset;
828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      switch ( fields->size )
829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
830727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case ( 8 / FT_CHAR_BIT ):
831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *(FT_Byte*)p = (FT_Byte)value;
832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
834727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case ( 16 / FT_CHAR_BIT ):
835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *(FT_UShort*)p = (FT_UShort)value;
836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
838727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case ( 32 / FT_CHAR_BIT ):
839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *(FT_UInt32*)p = (FT_UInt32)value;
840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      default:  /* for 64-bit systems */
843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *(FT_ULong*)p = (FT_ULong)value;
844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* go to next field */
847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      fields++;
848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    while ( 1 );
850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* close the frame if it was opened by this read */
853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( frame_accessed )
854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Stream_ExitFrame( stream );
855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */
861