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/*                                                                         */
7727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  Copyright 2000-2002, 2004-2006, 2008-2011, 2013 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;
42049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->cursor = 0;
43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->read   = 0;
44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->close  = 0;
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
98049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Stream_Seek( stream, (FT_ULong)( stream->pos + distance ) );
99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Long )
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 */
206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      stream->cursor = 0;
207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      stream->limit  = 0;
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    }
229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *pbytes = 0;
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 */
263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      stream->base = (unsigned char*)ft_mem_qalloc( memory, count, &error );
264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else
267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_QALLOC( stream->base, count ) )
268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* read it */
271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      read_bytes = stream->read( stream, stream->pos,
272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 stream->base, count );
273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( read_bytes < count )
274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
275295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_ERROR(( "FT_Stream_EnterFrame:"
276295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                   " invalid read; expected %lu bytes, got %lu\n",
277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   count, read_bytes ));
278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FREE( stream->base );
280727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        error = FT_THROW( Invalid_Stream_Operation );
281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      stream->cursor = stream->base;
283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      stream->limit  = stream->cursor + count;
284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      stream->pos   += read_bytes;
285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* check current and new position */
289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( stream->pos >= stream->size        ||
290aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich           stream->size - stream->pos < count )
291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
292295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_ERROR(( "FT_Stream_EnterFrame:"
293295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                   " invalid i/o; pos = 0x%lx, count = %lu, size = 0x%lx\n",
294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   stream->pos, count, stream->size ));
295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
296727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        error = FT_THROW( Invalid_Stream_Operation );
297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* set cursor */
301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      stream->cursor = stream->base + stream->pos;
302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      stream->limit  = stream->cursor + count;
303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      stream->pos   += count;
304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Stream_ExitFrame( FT_Stream  stream )
313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* IMPORTANT: The assertion stream->cursor != 0 was removed, given    */
315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*            that it is possible to access a frame of length 0 in    */
316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*            some weird fonts (usually, when accessing an array of   */
317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*            0 records, like in some strange kern tables).           */
318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                    */
319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*  In this case, the loader code handles the 0-length table          */
320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*  gracefully; however, stream.cursor is really set to 0 by the      */
321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*  FT_Stream_EnterFrame() call, and this is not an error.            */
322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                    */
323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( stream );
324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( stream->read )
326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Memory  memory = stream->memory;
328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_DEBUG_MEMORY
330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_mem_free( memory, stream->base );
331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      stream->base = NULL;
332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else
333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( stream->base );
334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->cursor = 0;
337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->limit  = 0;
338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Char )
342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Stream_GetChar( FT_Stream  stream )
343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Char  result;
345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( stream && stream->cursor );
348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    result = 0;
350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( stream->cursor < stream->limit )
351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      result = *stream->cursor++;
352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
357aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_BASE_DEF( FT_UShort )
358aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_Stream_GetUShort( FT_Stream  stream )
359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  p;
361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Short  result;
362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( stream && stream->cursor );
365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    result         = 0;
367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    p              = stream->cursor;
368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( p + 1 < stream->limit )
369aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner      result       = FT_NEXT_USHORT( p );
370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->cursor = p;
371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
376aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_BASE_DEF( FT_UShort )
377aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_Stream_GetUShortLE( FT_Stream  stream )
378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  p;
380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Short  result;
381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( stream && stream->cursor );
384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    result         = 0;
386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    p              = stream->cursor;
387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( p + 1 < stream->limit )
388aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner      result       = FT_NEXT_USHORT_LE( p );
389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->cursor = p;
390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
395aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_BASE_DEF( FT_ULong )
396aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_Stream_GetUOffset( FT_Stream  stream )
397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  p;
399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long   result;
400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( stream && stream->cursor );
403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    result         = 0;
405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    p              = stream->cursor;
406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( p + 2 < stream->limit )
407aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner      result       = FT_NEXT_UOFF3( p );
408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->cursor = p;
409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
413aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_BASE_DEF( FT_ULong )
414aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_Stream_GetULong( FT_Stream  stream )
415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  p;
417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long   result;
418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( stream && stream->cursor );
421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    result         = 0;
423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    p              = stream->cursor;
424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( p + 3 < stream->limit )
425aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner      result       = FT_NEXT_ULONG( p );
426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->cursor = p;
427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
431aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_BASE_DEF( FT_ULong )
432aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_Stream_GetULongLE( FT_Stream  stream )
433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  p;
435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long   result;
436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( stream && stream->cursor );
439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    result         = 0;
441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    p              = stream->cursor;
442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( p + 3 < stream->limit )
443aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner      result       = FT_NEXT_ULONG_LE( p );
444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->cursor = p;
445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Char )
450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Stream_ReadChar( FT_Stream  stream,
451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Error*  error )
452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte  result = 0;
454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( stream );
457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *error = FT_Err_Ok;
459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( stream->read )
461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( stream->read( stream, stream->pos, &result, 1L ) != 1L )
463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Fail;
464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( stream->pos < stream->size )
468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = stream->base[stream->pos];
469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Fail;
471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->pos++;
473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
477727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    *error = FT_THROW( Invalid_Stream_Operation );
478295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_ERROR(( "FT_Stream_ReadChar:"
479295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner               " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               stream->pos, stream->size ));
481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
486aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_BASE_DEF( FT_UShort )
487aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_Stream_ReadUShort( FT_Stream  stream,
488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                       FT_Error*  error )
489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte   reads[2];
491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  p = 0;
492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Short  result = 0;
493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( stream );
496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *error = FT_Err_Ok;
498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( stream->pos + 1 < stream->size )
500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( stream->read )
502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( stream->read( stream, stream->pos, reads, 2L ) != 2L )
504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Fail;
505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        p = reads;
507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        p = stream->base + stream->pos;
511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
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,
535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_Error*  error )
536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte   reads[2];
538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  p = 0;
539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Short  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      {
557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        p = stream->base + stream->pos;
558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( p )
561aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner        result = FT_NEXT_USHORT_LE( p );
562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->pos += 2;
567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
571727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    *error = FT_THROW( Invalid_Stream_Operation );
572aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_ERROR(( "FT_Stream_ReadUShortLE:"
573295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner               " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               stream->pos, stream->size ));
575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
580aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_BASE_DEF( FT_ULong )
581aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_Stream_ReadUOffset( FT_Stream  stream,
582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Error*  error )
583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte   reads[3];
585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  p = 0;
586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long   result = 0;
587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( stream );
590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *error = FT_Err_Ok;
592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( stream->pos + 2 < stream->size )
594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( stream->read )
596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if (stream->read( stream, stream->pos, reads, 3L ) != 3L )
598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Fail;
599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        p = reads;
601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        p = stream->base + stream->pos;
605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( p )
608aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner        result = FT_NEXT_UOFF3( p );
609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->pos += 3;
614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
618727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    *error = FT_THROW( Invalid_Stream_Operation );
619aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_ERROR(( "FT_Stream_ReadUOffset:"
620295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner               " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               stream->pos, stream->size ));
622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
627aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_BASE_DEF( FT_ULong )
628aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_Stream_ReadULong( FT_Stream  stream,
629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Error*  error )
630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte   reads[4];
632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  p = 0;
633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long   result = 0;
634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( stream );
637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *error = FT_Err_Ok;
639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( stream->pos + 3 < stream->size )
641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( stream->read )
643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( stream->read( stream, stream->pos, reads, 4L ) != 4L )
645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Fail;
646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        p = reads;
648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        p = stream->base + stream->pos;
652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( p )
655aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner        result = FT_NEXT_ULONG( p );
656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->pos += 4;
661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
665727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    *error = FT_THROW( Invalid_Stream_Operation );
666aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_ERROR(( "FT_Stream_ReadULong:"
667295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner               " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
668295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner               stream->pos, stream->size ));
669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
674aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_BASE_DEF( FT_ULong )
675aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  FT_Stream_ReadULongLE( FT_Stream  stream,
676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Error*  error )
677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte   reads[4];
679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  p = 0;
680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long   result = 0;
681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( stream );
684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *error = FT_Err_Ok;
686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( stream->pos + 3 < stream->size )
688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( stream->read )
690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( stream->read( stream, stream->pos, reads, 4L ) != 4L )
692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Fail;
693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        p = reads;
695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        p = stream->base + stream->pos;
699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( p )
702aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner        result = FT_NEXT_ULONG_LE( p );
703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->pos += 4;
708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
712727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    *error = FT_THROW( Invalid_Stream_Operation );
713aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_ERROR(( "FT_Stream_ReadULongLE:"
714295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner               " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
715295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner               stream->pos, stream->size ));
716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Stream_ReadFields( FT_Stream              stream,
723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        const FT_Frame_Field*  fields,
724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        void*                  structure )
725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error  error;
727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Bool   frame_accessed = 0;
7280a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    FT_Byte*  cursor;
729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
730727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !fields || !stream )
732727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
7340a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    cursor = stream->cursor;
7350a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Err_Ok;
737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    do
738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ULong  value;
740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int    sign_shift;
741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Byte*  p;
742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      switch ( fields->value )
745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_start:  /* access a new frame */
747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = FT_Stream_EnterFrame( stream, fields->offset );
748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        frame_accessed = 1;
752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        cursor         = stream->cursor;
753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        fields++;
754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        continue;  /* loop! */
755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_bytes:  /* read a byte sequence */
757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_skip:   /* skip some bytes      */
758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_UInt  len = fields->size;
760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( cursor + len > stream->limit )
763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
764727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            error = FT_THROW( Invalid_Stream_Operation );
765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Exit;
766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( fields->value == ft_frame_bytes )
769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            p = (FT_Byte*)structure + fields->offset;
771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_MEM_COPY( p, cursor, len );
772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          cursor += len;
774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          fields++;
775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          continue;
776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_byte:
779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_schar:  /* read a single byte */
780727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        value = FT_NEXT_BYTE( cursor );
781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        sign_shift = 24;
782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_short_be:
785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_ushort_be:  /* read a 2-byte big-endian short */
786727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        value = FT_NEXT_USHORT( cursor) ;
787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        sign_shift = 16;
788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_short_le:
791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_ushort_le:  /* read a 2-byte little-endian short */
792727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        value = FT_NEXT_USHORT_LE( cursor );
793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        sign_shift = 16;
794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_long_be:
797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_ulong_be:  /* read a 4-byte big-endian long */
798727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        value = FT_NEXT_ULONG( cursor );
799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        sign_shift = 0;
800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_long_le:
803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_ulong_le:  /* read a 4-byte little-endian long */
804727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        value = FT_NEXT_ULONG_LE( cursor );
805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        sign_shift = 0;
806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_off3_be:
809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_uoff3_be:  /* read a 3-byte big-endian long */
810727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        value = FT_NEXT_UOFF3( cursor );
811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        sign_shift = 8;
812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_off3_le:
815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case ft_frame_uoff3_le:  /* read a 3-byte little-endian long */
816727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        value = FT_NEXT_UOFF3_LE( cursor );
817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        sign_shift = 8;
818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      default:
821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* otherwise, exit the loop */
822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        stream->cursor = cursor;
823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* now, compute the signed value is necessary */
827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( fields->value & FT_FRAME_OP_SIGNED )
828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        value = (FT_ULong)( (FT_Int32)( value << sign_shift ) >> sign_shift );
829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* finally, store the value in the object */
831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      p = (FT_Byte*)structure + fields->offset;
833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      switch ( fields->size )
834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
835727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case ( 8 / FT_CHAR_BIT ):
836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *(FT_Byte*)p = (FT_Byte)value;
837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
839727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case ( 16 / FT_CHAR_BIT ):
840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *(FT_UShort*)p = (FT_UShort)value;
841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
843727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case ( 32 / FT_CHAR_BIT ):
844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *(FT_UInt32*)p = (FT_UInt32)value;
845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      default:  /* for 64-bit systems */
848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *(FT_ULong*)p = (FT_ULong)value;
849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* go to next field */
852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      fields++;
853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    while ( 1 );
855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* close the frame if it was opened by this read */
858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( frame_accessed )
859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Stream_ExitFrame( stream );
860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */
866