GRASS GIS 8 Programmer's Manual  8.5.0dev(2024)-bea8435a9e
safileio.c
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * Project: Shapelib
4  * Purpose: Default implementation of file io based on stdio.
5  * Author: Frank Warmerdam, warmerdam@pobox.com
6  *
7  ******************************************************************************
8  * Copyright (c) 2007, Frank Warmerdam
9  *
10  * SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
11  ******************************************************************************
12  *
13  */
14 
15 #include "shapefil.h"
16 
17 #include <assert.h>
18 #include <math.h>
19 #include <limits.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #ifdef SHPAPI_UTF8_HOOKS
25 #ifdef SHPAPI_WINDOWS
26 #define WIN32_LEAN_AND_MEAN
27 #define NOMINMAX
28 #include <windows.h>
29 #pragma comment(lib, "kernel32.lib")
30 #endif
31 #endif
32 
33 static SAFile SADFOpen(const char *pszFilename, const char *pszAccess,
34  void *pvUserData)
35 {
36  (void)pvUserData;
37  return (SAFile)fopen(pszFilename, pszAccess);
38 }
39 
40 static SAOffset SADFRead(void *p, SAOffset size, SAOffset nmemb, SAFile file)
41 {
42  return (SAOffset)fread(p, (size_t)size, (size_t)nmemb, (FILE *)file);
43 }
44 
45 static SAOffset SADFWrite(const void *p, SAOffset size, SAOffset nmemb,
46  SAFile file)
47 {
48  return (SAOffset)fwrite(p, (size_t)size, (size_t)nmemb, (FILE *)file);
49 }
50 
51 static SAOffset SADFSeek(SAFile file, SAOffset offset, int whence)
52 {
53 #if defined(_MSC_VER) && _MSC_VER >= 1400
54  return (SAOffset)_fseeki64((FILE *)file, (__int64)offset, whence);
55 #else
56  return (SAOffset)fseek((FILE *)file, (long)offset, whence);
57 #endif
58 }
59 
60 static SAOffset SADFTell(SAFile file)
61 {
62 #if defined(_MSC_VER) && _MSC_VER >= 1400
63  return (SAOffset)_ftelli64((FILE *)file);
64 #else
65  return (SAOffset)ftell((FILE *)file);
66 #endif
67 }
68 
69 static int SADFFlush(SAFile file)
70 {
71  return fflush((FILE *)file);
72 }
73 
74 static int SADFClose(SAFile file)
75 {
76  return fclose((FILE *)file);
77 }
78 
79 static int SADRemove(const char *filename, void *pvUserData)
80 {
81  (void)pvUserData;
82  return remove(filename);
83 }
84 
85 static void SADError(const char *message)
86 {
87  fprintf(stderr, "%s\n", message);
88 }
89 
91 {
92  psHooks->FOpen = SADFOpen;
93  psHooks->FRead = SADFRead;
94  psHooks->FWrite = SADFWrite;
95  psHooks->FSeek = SADFSeek;
96  psHooks->FTell = SADFTell;
97  psHooks->FFlush = SADFFlush;
98  psHooks->FClose = SADFClose;
99  psHooks->Remove = SADRemove;
100 
101  psHooks->Error = SADError;
102  psHooks->Atof = atof;
103  psHooks->pvUserData = NULL;
104 }
105 
106 #ifdef SHPAPI_WINDOWS
107 
108 static wchar_t *Utf8ToWideChar(const char *pszFilename)
109 {
110  const int nMulti = (int)strlen(pszFilename) + 1;
111  const int nWide =
112  MultiByteToWideChar(CP_UTF8, 0, pszFilename, nMulti, 0, 0);
113  if (nWide == 0) {
114  return NULL;
115  }
116  wchar_t *pwszFileName = (wchar_t *)malloc(nWide * sizeof(wchar_t));
117  if (pwszFileName == NULL) {
118  return NULL;
119  }
120  if (MultiByteToWideChar(CP_UTF8, 0, pszFilename, nMulti, pwszFileName,
121  nWide) == 0) {
122  free(pwszFileName);
123  return NULL;
124  }
125  return pwszFileName;
126 }
127 
128 /************************************************************************/
129 /* SAUtf8WFOpen */
130 /************************************************************************/
131 
132 static SAFile SAUtf8WFOpen(const char *pszFilename, const char *pszAccess,
133  void *pvUserData)
134 {
135  (void)pvUserData;
136  SAFile file = NULL;
137  wchar_t *pwszFileName = Utf8ToWideChar(pszFilename);
138  wchar_t *pwszAccess = Utf8ToWideChar(pszAccess);
139  if (pwszFileName != NULL && pwszAccess != NULL) {
140  file = (SAFile)_wfopen(pwszFileName, pwszAccess);
141  }
142  free(pwszFileName);
143  free(pwszAccess);
144  return file;
145 }
146 
147 static int SAUtf8WRemove(const char *pszFilename, void *pvUserData)
148 {
149  (void)pvUserData;
150  wchar_t *pwszFileName = Utf8ToWideChar(pszFilename);
151  int rc = -1;
152  if (pwszFileName != NULL) {
153  rc = _wremove(pwszFileName);
154  }
155  free(pwszFileName);
156  return rc;
157 }
158 
159 #endif
160 
161 #ifdef SHPAPI_UTF8_HOOKS
162 #ifndef SHPAPI_WINDOWS
163 #error "no implementations of UTF-8 hooks available for this platform"
164 #endif
165 
166 void SASetupUtf8Hooks(SAHooks *psHooks)
167 {
168  psHooks->FOpen = SAUtf8WFOpen;
169  psHooks->Remove = SAUtf8WRemove;
170  psHooks->FRead = SADFRead;
171  psHooks->FWrite = SADFWrite;
172  psHooks->FSeek = SADFSeek;
173  psHooks->FTell = SADFTell;
174  psHooks->FFlush = SADFFlush;
175  psHooks->FClose = SADFClose;
176 
177  psHooks->Error = SADError;
178  psHooks->Atof = atof;
179 }
180 #endif
#define NULL
Definition: ccmath.h:32
#define file
void SASetupDefaultHooks(SAHooks *psHooks)
Definition: safileio.c:90
int * SAFile
Definition: shapefil.h:125
unsigned long SAOffset
Definition: shapefil.h:131
void * malloc(YYSIZE_T)
void free(void *)
void(* Error)(const char *message)
Definition: shapefil.h:146
SAOffset(* FTell)(SAFile file)
Definition: shapefil.h:141
int(* FFlush)(SAFile file)
Definition: shapefil.h:142
SAFile(* FOpen)(const char *filename, const char *access, void *pvUserData)
Definition: shapefil.h:136
double(* Atof)(const char *str)
Definition: shapefil.h:147
void * pvUserData
Definition: shapefil.h:148
SAOffset(* FWrite)(const void *p, SAOffset size, SAOffset nmemb, SAFile file)
Definition: shapefil.h:138
int(* FClose)(SAFile file)
Definition: shapefil.h:143
int(* Remove)(const char *filename, void *pvUserData)
Definition: shapefil.h:144
SAOffset(* FRead)(void *p, SAOffset size, SAOffset nmemb, SAFile file)
Definition: shapefil.h:137
SAOffset(* FSeek)(SAFile file, SAOffset offset, int whence)
Definition: shapefil.h:140