xref: /aosp_15_r20/external/sandboxed-api/contrib/libxls/utils/utils_libxls.cc (revision ec63e07ab9515d95e79c211197c445ef84cefa6a)
1 // Copyright 2022 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "contrib/libxls/utils/utils_libxls.h"
16 
17 #include <fstream>
18 #include <iostream>
19 #include <string>
20 
21 #include "contrib/libxls/sandboxed.h"
22 
GetError(LibxlsApi * api,xls_error_t error_code)23 absl::Status GetError(LibxlsApi* api, xls_error_t error_code) {
24   SAPI_ASSIGN_OR_RETURN(const char* c_errstr, api->xls_getError(error_code));
25   sapi::v::RemotePtr sapi_errstr(const_cast<char*>(c_errstr));
26   SAPI_ASSIGN_OR_RETURN(std::string errstr,
27                         api->GetSandbox()->GetCString(sapi_errstr));
28 
29   return absl::UnavailableError(errstr);
30 }
31 
Open(LibxlsSapiSandbox * sandbox,const std::string & filename,const std::string & encode)32 absl::StatusOr<LibXlsWorkbook> LibXlsWorkbook::Open(LibxlsSapiSandbox* sandbox,
33                                                     const std::string& filename,
34                                                     const std::string& encode) {
35   if (sandbox == nullptr) {
36     return absl::InvalidArgumentError("Sandbox has to be defined");
37   }
38 
39   LibxlsApi api(sandbox);
40 
41   sapi::v::IntBase<xls_error_t> sapi_error;
42   sapi::v::CStr sapi_filename(filename.c_str());
43   sapi::v::CStr sapi_encode(encode.c_str());
44 
45   SAPI_ASSIGN_OR_RETURN(
46       xlsWorkBook * wb,
47       api.xls_open_file(sapi_filename.PtrBefore(), sapi_encode.PtrBefore(),
48                         sapi_error.PtrAfter()));
49 
50   if (wb == nullptr) {
51     return GetError(&api, sapi_error.GetValue());
52   }
53 
54   sapi::v::Struct<xlsWorkBook> sapi_wb;
55   sapi_wb.SetRemote(wb);
56   SAPI_RETURN_IF_ERROR(sandbox->TransferFromSandboxee(&sapi_wb));
57 
58   return LibXlsWorkbook(sandbox, wb, sapi_wb.data().sheets.count);
59 }
60 
~LibXlsWorkbook()61 LibXlsWorkbook::~LibXlsWorkbook() {
62   if (rwb_ != nullptr) {
63     sapi::v::RemotePtr sapi_rwb(rwb_);
64     LibxlsApi api(sandbox_);
65     api.xls_close_WB(&sapi_rwb).IgnoreError();
66   }
67 }
68 
GetSheetCount()69 size_t LibXlsWorkbook::GetSheetCount() { return sheet_count_; }
70 
OpenSheet(uint32_t index)71 absl::StatusOr<LibXlsSheet> LibXlsWorkbook::OpenSheet(uint32_t index) {
72   if (GetSheetCount() <= index) {
73     return absl::OutOfRangeError("Index out of range");
74   }
75 
76   LibxlsApi api(sandbox_);
77   sapi::v::RemotePtr sapi_rwb(rwb_);
78   SAPI_ASSIGN_OR_RETURN(xlsWorkSheet * ws,
79                         api.xls_getWorkSheet(&sapi_rwb, index));
80   if (ws == nullptr) {
81     return absl::UnavailableError("Unable to open sheet");
82   }
83 
84   sapi::v::Struct<xlsWorkSheet> sapi_ws;
85   sapi_ws.SetRemote(ws);
86   SAPI_ASSIGN_OR_RETURN(xls_error_t error_code,
87                         api.xls_parseWorkSheet(sapi_ws.PtrAfter()));
88   if (error_code != 0) {
89     return GetError(&api, error_code);
90   }
91 
92   return LibXlsSheet(sandbox_, ws, sapi_ws.data().rows.lastrow + 1,
93                      sapi_ws.data().rows.lastcol + 1);
94 }
95 
GetRowCount() const96 size_t LibXlsSheet::GetRowCount() const { return row_; }
97 
GetColCount() const98 size_t LibXlsSheet::GetColCount() const { return col_; }
99 
GetStr(const sapi::v::Struct<xlsCell> & sapi_cell)100 absl::StatusOr<std::string> LibXlsSheet::GetStr(
101     const sapi::v::Struct<xlsCell>& sapi_cell) {
102   if (sapi_cell.data().str == nullptr) {
103     return "";
104   }
105 
106   sapi::v::RemotePtr sapi_str(sapi_cell.data().str);
107   return sandbox_->GetCString(sapi_str);
108 }
109 
GetNewCell(const sapi::v::Struct<xlsCell> & sapi_cell)110 absl::StatusOr<LibXlsCell> LibXlsSheet::GetNewCell(
111     const sapi::v::Struct<xlsCell>& sapi_cell) {
112   int id = sapi_cell.data().id;
113   double d = sapi_cell.data().d;
114 
115   switch (id) {
116     case XLS_RECORD_RK:
117     case XLS_RECORD_MULRK:
118     case XLS_RECORD_NUMBER:
119       return LibXlsCell{XLS_RECORD_NUMBER, d};
120     case XLS_RECORD_BLANK:
121       return LibXlsCell{XLS_RECORD_BLANK, 0.0};
122     case XLS_RECORD_FORMULA:
123       SAPI_ASSIGN_OR_RETURN(std::string cell_str, GetStr(sapi_cell));
124       if (cell_str == "bool") {
125         return LibXlsCell{XLS_RECORD_BOOL, d > 0};
126       } else if (cell_str == "error") {
127         return LibXlsCell{XLS_RECORD_ERROR, cell_str};
128       }
129       return LibXlsCell{XLS_RECORD_STRING, cell_str};
130   }
131 
132   return absl::UnavailableError("Unknown type");
133 }
134 
GetCell(uint32_t row,uint32_t col)135 absl::StatusOr<LibXlsCell> LibXlsSheet::GetCell(uint32_t row, uint32_t col) {
136   if (row >= GetRowCount()) {
137     return absl::OutOfRangeError("Row out of range");
138   }
139   if (col >= GetColCount()) {
140     return absl::OutOfRangeError("Col out of range");
141   }
142 
143   LibxlsApi api(sandbox_);
144   sapi::v::RemotePtr sapi_rws(rws_);
145   SAPI_ASSIGN_OR_RETURN(xlsCell * cell, api.xls_cell(&sapi_rws, row, col));
146   if (cell == nullptr) {
147     return absl::UnavailableError("Unable to get cell");
148   }
149   sapi::v::Struct<xlsCell> sapi_cell;
150   sapi_cell.SetRemote(cell);
151   SAPI_RETURN_IF_ERROR(sandbox_->TransferFromSandboxee(&sapi_cell));
152 
153   return GetNewCell(sapi_cell);
154 }
155 
~LibXlsSheet()156 LibXlsSheet::~LibXlsSheet() {
157   if (rws_ != nullptr) {
158     LibxlsApi api(sandbox_);
159     sapi::v::RemotePtr sapi_rws(rws_);
160     api.xls_close_WS(&sapi_rws).IgnoreError();
161   }
162 }
163